summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-03-05 13:28:54 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2019-03-06 10:16:49 -0500
commitb78f4604658dc875221bda5a23423cb34742e428 (patch)
tree6e5c59ff608340146e6cc484e3ad57aa5cf7759e
parent201c4a60e4b8af56d9c02a3675d1443ba4171c89 (diff)
downloadsqlalchemy-b78f4604658dc875221bda5a23423cb34742e428.tar.gz
Ensure association proxy works over synonym
Fixed regression where an association proxy linked to a synonym would no longer work, both at instance level and at class level. Fixes: #4522 Change-Id: I949079229ef87c12736c362df35444f6e30c8038
-rw-r--r--doc/build/changelog/unreleased_13/4522.rst6
-rw-r--r--lib/sqlalchemy/orm/descriptor_props.py4
-rw-r--r--test/ext/test_associationproxy.py52
3 files changed, 62 insertions, 0 deletions
diff --git a/doc/build/changelog/unreleased_13/4522.rst b/doc/build/changelog/unreleased_13/4522.rst
new file mode 100644
index 000000000..cd0729600
--- /dev/null
+++ b/doc/build/changelog/unreleased_13/4522.rst
@@ -0,0 +1,6 @@
+.. change::
+ :tags: bug, orm, ext
+ :tickets: 4522
+
+ Fixed regression where an association proxy linked to a synonym would no
+ longer work, both at instance level and at class level.
diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py
index a0ddf3a8b..28b3bc5db 100644
--- a/lib/sqlalchemy/orm/descriptor_props.py
+++ b/lib/sqlalchemy/orm/descriptor_props.py
@@ -39,6 +39,10 @@ class DescriptorProperty(MapperProperty):
expire_missing = True
collection = False
+ @property
+ def uses_objects(self):
+ return getattr(mapper.class_, prop.name).impl.uses_objects
+
def __init__(self, key):
self.key = key
diff --git a/test/ext/test_associationproxy.py b/test/ext/test_associationproxy.py
index 4b07a383d..6f701416c 100644
--- a/test/ext/test_associationproxy.py
+++ b/test/ext/test_associationproxy.py
@@ -3089,6 +3089,58 @@ class MultiOwnerTest(
self._assert_raises_ambiguous(lambda: D.c_data.any(B.id == 5))
+class ProxyOfSynonymTest(AssertsCompiledSQL, fixtures.DeclarativeMappedTest):
+ __dialect__ = "default"
+
+ run_create_tables = None
+
+ @classmethod
+ def setup_classes(cls):
+ from sqlalchemy.orm import synonym
+
+ Base = cls.DeclarativeBasic
+
+ class A(Base):
+ __tablename__ = "a"
+
+ id = Column(Integer, primary_key=True)
+ data = Column(String)
+ bs = relationship("B", backref="a")
+ data_syn = synonym("data")
+
+ b_data = association_proxy("bs", "data_syn")
+
+ class B(Base):
+ __tablename__ = "b"
+ id = Column(Integer, primary_key=True)
+ a_id = Column(ForeignKey("a.id"))
+ data = Column(String)
+ data_syn = synonym("data")
+
+ a_data = association_proxy("a", "data_syn")
+
+ def test_o2m_instance_getter(self):
+ A, B = self.classes("A", "B")
+
+ a1 = A(bs=[B(data="bdata1"), B(data="bdata2")])
+ eq_(a1.b_data, ["bdata1", "bdata2"])
+
+ def test_m2o_instance_getter(self):
+ A, B = self.classes("A", "B")
+
+ b1 = B(a=A(data="adata"))
+ eq_(b1.a_data, "adata")
+
+ def test_o2m_expr(self):
+ A, B = self.classes("A", "B")
+
+ self.assert_compile(
+ A.b_data == "foo",
+ "EXISTS (SELECT 1 FROM a, b WHERE a.id = b.a_id "
+ "AND b.data = :data_1)",
+ )
+
+
class ProxyAttrTest(fixtures.DeclarativeMappedTest):
@classmethod
def setup_classes(cls):