summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-01-16 12:10:08 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2017-01-16 13:16:25 -0500
commit3aefc6e8a4a02892de91bdac9a917d1697c90ea6 (patch)
tree0f06fa7e2831d266142f4d831de8f62979eca9ec /test
parent710ce4aaf9130cce0ad17cc471be57038dd641aa (diff)
downloadsqlalchemy-3aefc6e8a4a02892de91bdac9a917d1697c90ea6.tar.gz
Add "existing" populators for subqueryload
Fixed bug in subquery loading where an object encountered as an "existing" row, e.g. already loaded from a different path in the same query, would not invoke subquery loaders for unloaded attributes that specified this loading. This issue is in the same area as that of :ticket:`3431`, :ticket:`3811` which involved similar issues with joined loading. Change-Id: If111a76b0812010905b0ac811276a816779d297f Fixes: #3854
Diffstat (limited to 'test')
-rw-r--r--test/orm/test_subquery_relations.py121
1 files changed, 120 insertions, 1 deletions
diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py
index c8e8636fe..ce9926058 100644
--- a/test/orm/test_subquery_relations.py
+++ b/test/orm/test_subquery_relations.py
@@ -1,4 +1,4 @@
-from sqlalchemy.testing import eq_, is_, is_not_
+from sqlalchemy.testing import eq_, is_, is_not_, is_true
from sqlalchemy import testing
from sqlalchemy.testing.schema import Table, Column
from sqlalchemy import Integer, String, ForeignKey, bindparam, inspect
@@ -2072,3 +2072,122 @@ class JoinedNoLoadConflictTest(fixtures.DeclarativeMappedTest):
[Child(name='c1')]
)
+
+class TestExistingRowPopulation(fixtures.DeclarativeMappedTest):
+ @classmethod
+ def setup_classes(cls):
+ Base = cls.DeclarativeBasic
+
+ class A(Base):
+ __tablename__ = 'a'
+
+ id = Column(Integer, primary_key=True)
+ b_id = Column(ForeignKey('b.id'))
+ a2_id = Column(ForeignKey('a2.id'))
+ a2 = relationship("A2")
+ b = relationship("B")
+
+ class A2(Base):
+ __tablename__ = 'a2'
+
+ id = Column(Integer, primary_key=True)
+ b_id = Column(ForeignKey('b.id'))
+ b = relationship("B")
+
+ class B(Base):
+ __tablename__ = 'b'
+
+ id = Column(Integer, primary_key=True)
+
+ c1_m2o_id = Column(ForeignKey('c1_m2o.id'))
+ c2_m2o_id = Column(ForeignKey('c2_m2o.id'))
+
+ c1_o2m = relationship("C1o2m")
+ c2_o2m = relationship("C2o2m")
+ c1_m2o = relationship("C1m2o")
+ c2_m2o = relationship("C2m2o")
+
+ class C1o2m(Base):
+ __tablename__ = 'c1_o2m'
+
+ id = Column(Integer, primary_key=True)
+ b_id = Column(ForeignKey('b.id'))
+
+ class C2o2m(Base):
+ __tablename__ = 'c2_o2m'
+
+ id = Column(Integer, primary_key=True)
+ b_id = Column(ForeignKey('b.id'))
+
+ class C1m2o(Base):
+ __tablename__ = 'c1_m2o'
+
+ id = Column(Integer, primary_key=True)
+
+ class C2m2o(Base):
+ __tablename__ = 'c2_m2o'
+
+ id = Column(Integer, primary_key=True)
+
+ @classmethod
+ def insert_data(cls):
+ A, A2, B, C1o2m, C2o2m, C1m2o, C2m2o = cls.classes(
+ 'A', 'A2', 'B', 'C1o2m', 'C2o2m', 'C1m2o', 'C2m2o'
+ )
+
+ s = Session()
+
+ b = B(
+ c1_o2m=[C1o2m()],
+ c2_o2m=[C2o2m()],
+ c1_m2o=C1m2o(),
+ c2_m2o=C2m2o(),
+ )
+
+ s.add(A(b=b, a2=A2(b=b)))
+ s.commit()
+
+ def test_o2m(self):
+ A, A2, B, C1o2m, C2o2m = self.classes(
+ 'A', 'A2', 'B', 'C1o2m', 'C2o2m'
+ )
+
+ s = Session()
+
+ # A -J-> B -L-> C1
+ # A -J-> B -S-> C2
+
+ # A -J-> A2 -J-> B -S-> C1
+ # A -J-> A2 -J-> B -L-> C2
+
+ q = s.query(A).options(
+ joinedload(A.b).subqueryload(B.c2_o2m),
+ joinedload(A.a2).joinedload(A2.b).subqueryload(B.c1_o2m)
+ )
+
+ a1 = q.all()[0]
+
+ is_true('c1_o2m' in a1.b.__dict__)
+ is_true('c2_o2m' in a1.b.__dict__)
+
+ def test_m2o(self):
+ A, A2, B, C1m2o, C2m2o = self.classes(
+ 'A', 'A2', 'B', 'C1m2o', 'C2m2o'
+ )
+
+ s = Session()
+
+ # A -J-> B -L-> C1
+ # A -J-> B -S-> C2
+
+ # A -J-> A2 -J-> B -S-> C1
+ # A -J-> A2 -J-> B -L-> C2
+
+ q = s.query(A).options(
+ joinedload(A.b).subqueryload(B.c2_m2o),
+ joinedload(A.a2).joinedload(A2.b).subqueryload(B.c1_m2o)
+ )
+
+ a1 = q.all()[0]
+ is_true('c1_m2o' in a1.b.__dict__)
+ is_true('c2_m2o' in a1.b.__dict__)