Show
Ignore:
Timestamp:
09/29/09 14:14:37 (4 years ago)
Author:
ged
Message:

- changed the M2M column format again (only differ from the 0.6.x naming for

selfref M2M) and use the inverse relationship name to produce more sensible
column names.

- added a test simulating a migration from the old column format to the new

one.

- added lots of comments to explain what the different variables you can use in

the M2M format strings actually mean.

- changed the migration_aid_m2m_column_formatter so that the method can be

reused to migrate from any format to any format.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • elixir/trunk/tests/test_m2m.py

    r464 r475  
    1717    def test_simple(self): 
    1818        class A(Entity): 
    19             name = Field(String(60)) 
    20             bs_ = ManyToMany('B') 
    21  
    22         class B(Entity): 
     19            using_options(shortnames=True) 
     20            name = Field(String(60)) 
     21            as_ = ManyToMany('A') 
     22            bs_ = ManyToMany('B') 
     23 
     24        class B(Entity): 
     25            using_options(shortnames=True) 
    2326            name = Field(String(60)) 
    2427            as_ = ManyToMany('A') 
     
    3336        # check column names 
    3437        m2m_cols = m2m_table.columns 
    35         assert 'bs__id' in m2m_cols 
     38        assert 'a_id' in m2m_cols 
     39        assert 'b_id' in m2m_cols 
     40 
     41        # check selfref m2m table column names were generated correctly 
     42        m2m_cols = A.as_.property.secondary.columns 
    3643        assert 'as__id' in m2m_cols 
     44        assert 'inverse_id' in m2m_cols 
    3745 
    3846        # check the relationships work as expected 
     
    7684        # this needs to be done before declaring the classes 
    7785        elixir.options.M2MCOL_NAMEFORMAT = \ 
    78             elixir.relationships.alternate_m2m_column_formatter 
     86            elixir.options.ALTERNATE_M2MCOL_NAMEFORMAT 
    7987 
    8088        class A(Entity): 
     
    93101        # check m2m table column names were generated correctly 
    94102        m2m_cols = A.bs_.property.secondary.columns 
    95         assert '%s_id' % A.table.name in m2m_cols 
    96         assert '%s_id' % B.table.name in m2m_cols 
     103        assert 'as__id' in m2m_cols 
     104        assert 'bs__id' in m2m_cols 
    97105 
    98106        # check selfref m2m table column names were generated correctly 
     
    101109        assert 'inverse_id' in m2m_cols 
    102110 
    103     #TODO: add an upgrade test 
    104     #def test_upgrade(self): 
    105 #        elixir.options.M2MCOL_NAMEFORMAT = elixir.options.OLD_M2MCOL_NAMEFORMAT 
     111    def test_upgrade(self): 
     112        elixir.options.M2MCOL_NAMEFORMAT = elixir.options.OLD_M2MCOL_NAMEFORMAT 
     113 
     114        class A(Entity): 
     115            using_options(shortnames=True) 
     116            name = Field(String(20)) 
     117            links_to = ManyToMany('A') 
     118            is_linked_from = ManyToMany('A') 
     119            bs_ = ManyToMany('B') 
     120 
     121        class B(Entity): 
     122            using_options(shortnames=True) 
     123            name = Field(String(20)) 
     124            as_ = ManyToMany('A') 
     125 
     126        setup_all(True) 
     127 
     128        a = A(name='a1', links_to=[A(name='a2')]) 
     129 
     130        session.commit() 
     131        session.clear() 
     132 
     133        del A 
     134        del B 
     135 
     136        # do not drop the tables, that's the whole point! 
     137        cleanup_all() 
     138 
     139        # simulate a renaming of columns (as given by the migration aid) 
     140        # 'a_id1' to 'is_linked_from_id'. 
     141        # 'a_id2' to 'links_to_id'. 
     142        conn = metadata.bind.connect() 
     143        conn.execute("ALTER TABLE a_links_to__a_is_linked_from RENAME TO temp") 
     144        conn.execute("CREATE TABLE a_links_to__a_is_linked_from (" 
     145                        "is_linked_from_id INTEGER NOT NULL, " 
     146                        "links_to_id INTEGER NOT NULL, " 
     147                     "PRIMARY KEY (is_linked_from_id, links_to_id), " 
     148                     "CONSTRAINT a_fk1 FOREIGN KEY(is_linked_from_id) " 
     149                                      "REFERENCES a (id), " 
     150                     "CONSTRAINT a_fk2 FOREIGN KEY(links_to_id) " 
     151                                      "REFERENCES a (id))") 
     152        conn.execute("INSERT INTO a_links_to__a_is_linked_from " 
     153                     "(is_linked_from_id, links_to_id) " 
     154                     "SELECT a_id1, a_id2 FROM temp") 
     155        conn.close() 
     156 
     157        # ... 
     158        elixir.options.M2MCOL_NAMEFORMAT = elixir.options.NEW_M2MCOL_NAMEFORMAT 
    106159#        elixir.options.MIGRATION_TO_07_AID = True 
    107 #        metadata.bind = 'sqlite://' 
    108 #        elixir.options.M2MCOL_NAMEFORMAT = elixir.options.NEW_M2MCOL_NAMEFORMAT    #    assert False 
     160 
     161        class A(Entity): 
     162            using_options(shortnames=True) 
     163            name = Field(String(20)) 
     164            links_to = ManyToMany('A') 
     165            is_linked_from = ManyToMany('A') 
     166            bs_ = ManyToMany('B') 
     167 
     168        class B(Entity): 
     169            using_options(shortnames=True) 
     170            name = Field(String(20)) 
     171            as_ = ManyToMany('A') 
     172 
     173        setup_all() 
     174 
     175        a1 = A.get_by(name='a1') 
     176        assert len(a1.links_to) == 1 
     177        assert not a1.is_linked_from 
     178 
     179        a2 = a1.links_to[0] 
     180        assert a2.name == 'a2' 
     181        assert not a2.links_to 
     182        assert a2.is_linked_from == [a1] 
    109183 
    110184    def test_manual_column_format(self):