summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-04-11 19:37:56 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-04-11 19:37:56 +0000
commit95520005d5469f311f53ea9c51bbaef61be89178 (patch)
tree33850e7fe5bdaa6e77ddd892d87995e169fc7a7b
parenta4b8112d6d919eded664b042aea4f8015e143110 (diff)
downloadsqlalchemy-95520005d5469f311f53ea9c51bbaef61be89178.tar.gz
- fix to many-to-many relationships targeting polymorphic mappers
[ticket:533]
-rw-r--r--CHANGES2
-rw-r--r--lib/sqlalchemy/orm/properties.py2
-rw-r--r--test/orm/inheritance5.py50
3 files changed, 54 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index 458763a13..ba99f5e33 100644
--- 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 (?!)
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index e3bd98e3e..1b6203e06 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -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:
diff --git a/test/orm/inheritance5.py b/test/orm/inheritance5.py
index bdc9e02e1..657530405 100644
--- a/test/orm/inheritance5.py
+++ b/test/orm/inheritance5.py
@@ -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()