diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/properties.py | 2 | ||||
-rw-r--r-- | test/orm/relationships.py | 31 |
3 files changed, 37 insertions, 0 deletions
@@ -57,6 +57,10 @@ CHANGES added to a mapper post-compile using add_property() or equivalent. + - Fixed bug where many-to-many relation() with + viewonly=True would not correctly reference the + link between secondary->remote. + - Duplicate items in a list-based collection will be maintained when issuing INSERTs to a "secondary" table in a many-to-many relation. diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 87ad6819e..93fae0837 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -793,6 +793,8 @@ class RelationProperty(StrategizedProperty): else: if self.viewonly: eq_pairs = self.synchronize_pairs + if self.secondaryjoin: + eq_pairs += self.secondary_synchronize_pairs else: eq_pairs = criterion_as_pairs(self.primaryjoin, consider_as_foreign_keys=self._foreign_keys, any_operator=True) if self.secondaryjoin: diff --git a/test/orm/relationships.py b/test/orm/relationships.py index 22665f990..181ed375c 100644 --- a/test/orm/relationships.py +++ b/test/orm/relationships.py @@ -1004,7 +1004,38 @@ class ViewOnlyUniqueNames(_base.MappedTest): assert set([x.t2id for x in c1.t2s]) == set([c2a.t2id, c2b.t2id]) assert set([x.t2id for x in c1.t2_view]) == set([c2b.t2id]) +class ViewOnlyLocalRemoteM2M(testing.TestBase): + """test that local-remote is correctly determined for m2m""" + + def test_local_remote(self): + meta = MetaData() + + t1 = Table('t1', meta, + Column('id', Integer, primary_key=True), + ) + t2 = Table('t2', meta, + Column('id', Integer, primary_key=True), + ) + t12 = Table('tab', meta, + Column('t1_id', Integer, ForeignKey('t1.id',)), + Column('t2_id', Integer, ForeignKey('t2.id',)), + ) + + class A(object): pass + class B(object): pass + mapper( B, t2, ) + m = mapper( A, t1, properties=dict( + b_view = relation( B, secondary=t12, viewonly=True), + b_plain= relation( B, secondary=t12), + ) + ) + compile_mappers() + assert m.get_property('b_view').local_remote_pairs == \ + m.get_property('b_plain').local_remote_pairs == \ + [(t1.c.id, t12.c.t1_id), (t12.c.t2_id, t2.c.id)] + + class ViewOnlyNonEquijoin(_base.MappedTest): """'viewonly' mappings based on non-equijoins.""" |