]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- fix to many-to-many relationships targeting polymorphic mappers
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 11 Apr 2007 19:37:56 +0000 (19:37 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 11 Apr 2007 19:37:56 +0000 (19:37 +0000)
[ticket:533]

CHANGES
lib/sqlalchemy/orm/properties.py
test/orm/inheritance5.py

diff --git a/CHANGES b/CHANGES
index 458763a13d3aa8e05c7a9d4ff1b3374da70e4611..ba99f5e33084f033ab3d965dd49d67323c583b35 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -48,6 +48,8 @@
     - improved/fixed custom collection classes when giving it "set"/
       "sets.Set" classes or subclasses (was still looking for append()
       methods on them during lazy loads)
+    - fix to many-to-many relationships targeting polymorphic mappers
+      [ticket:533]
 - sqlite:
     - removed silly behavior where sqlite would reflect UNIQUE indexes
       as part of the primary key (?!)
index e3bd98e3e183c16d3cab97a47e3e7a32a35cd1cc..1b6203e063d239fba3e53a974115b4ebe4f72f88 100644 (file)
@@ -384,6 +384,8 @@ class PropertyLoader(StrategizedProperty):
             # load "polymorphic" versions of the columns present in "remote_side" - this is
             # important for lazy-clause generation which goes off the polymorphic target selectable
             for c in list(self.remote_side):
+                if self.secondary and c in self.secondary.columns:
+                    continue
                 for equiv in [c] + (c in target_equivalents and target_equivalents[c] or []): 
                     corr = self.mapper.select_table.corresponding_column(equiv, raiseerr=False)
                     if corr:
index bdc9e02e121f4e10acc42a6c63a157db48c9a5e1..65753040568d718d1d528306a3925fb236858216 100644 (file)
@@ -777,6 +777,56 @@ class MultiLevelTest(testbase.ORMTest):
         assert set(session.query(Employee).select()) == set([a,b,c])
         assert set(session.query( Engineer).select()) == set([b,c])
         assert session.query( Manager).select() == [c]
+
+class ManyToManyPolyTest(testbase.ORMTest):
+    def define_tables(self, metadata):
+        global base_item_table, item_table, base_item_collection_table, collection_table
+        base_item_table = Table(
+            'base_item', metadata,
+            Column('id', Integer, primary_key=True),
+            Column('child_name', String(255), default=None))
+
+        item_table = Table(
+            'item', metadata,
+            Column('id', Integer, ForeignKey('base_item.id'), primary_key=True),
+            Column('dummy', Integer, default=0)) # Dummy column to avoid weird insert problems
+
+        base_item_collection_table = Table(
+            'base_item_collection', metadata,
+            Column('item_id', Integer, ForeignKey('base_item.id')),
+            Column('collection_id', Integer, ForeignKey('collection.id')))
+
+        collection_table = Table(
+            'collection', metadata,
+            Column('id', Integer, primary_key=True),
+            Column('name', Unicode(255)))
+            
+    def test_pjoin_compile(self):
+        """test that remote_side columns in the secondary join table arent attempted to be 
+        matched to the target polymorphic selectable"""
+        class BaseItem(object): pass
+        class Item(BaseItem): pass
+        class Collection(object): pass
+        item_join = polymorphic_union( {
+            'BaseItem':base_item_table.select(base_item_table.c.child_name=='BaseItem'),
+            'Item':base_item_table.join(item_table),
+            }, None, 'item_join')
+
+        mapper(
+            BaseItem, base_item_table,
+            select_table=item_join,
+            polymorphic_on=base_item_table.c.child_name,
+            polymorphic_identity='BaseItem',
+            properties=dict(collections=relation(Collection, secondary=base_item_collection_table, backref="items")))
+
+        mapper(
+            Item, item_table,
+            inherits=BaseItem,
+            polymorphic_identity='Item')
+
+        mapper(Collection, collection_table)
+        
+        class_mapper(BaseItem)
         
 if __name__ == "__main__":    
     testbase.main()