self.params = params
self.propagated_loader_options = {
- o for o in statement._with_options if o.propagate_to_loaders
+ # issue 7447.
+ # propagated loader options will be present on loaded InstanceState
+ # objects under state.load_options and are typically used by
+ # LazyLoader to apply options to the SELECT statement it emits.
+ # For compile state options (i.e. loader strategy options), these
+ # need to line up with the ".load_path" attribute which in
+ # loader.py is pulled from context.compile_state.current_path.
+ # so, this means these options have to be the ones from the
+ # *cached* statement that's travelling with compile_state, not the
+ # *current* statement which won't match up for an ad-hoc
+ # AliasedClass
+ cached_o
+ for cached_o in compile_state.select_statement._with_options
+ if cached_o.propagate_to_loaders and cached_o._is_compile_state
+ } | {
+ # for user defined loader options that are not "compile state",
+ # those just need to be present as they are
+ uncached_o
+ for uncached_o in statement._with_options
+ if uncached_o.propagate_to_loaders
+ and not uncached_o._is_compile_state
}
self.attributes = dict(compile_state.attributes)
def test_lazyload_aliased_abs_bcs_one(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(aa, A)
- .filter(aa.id == 1)
- .filter(A.id == 2)
- .filter(aa.id != A.id)
- .options(joinedload(A.bs).joinedload(B.cs))
- )
- self._run_tests(q, 3)
+
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(aa, A)
+ .filter(aa.id == 1)
+ .filter(A.id == 2)
+ .filter(aa.id != A.id)
+ .options(joinedload(A.bs).joinedload(B.cs))
+ )
+ self._run_tests(q, 3)
def test_lazyload_aliased_abs_bcs_two(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(aa, A)
- .filter(aa.id == 1)
- .filter(A.id == 2)
- .filter(aa.id != A.id)
- .options(defaultload(A.bs).joinedload(B.cs))
- )
- self._run_tests(q, 3)
+
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(aa, A)
+ .filter(aa.id == 1)
+ .filter(A.id == 2)
+ .filter(aa.id != A.id)
+ .options(defaultload(A.bs).joinedload(B.cs))
+ )
+ self._run_tests(q, 3)
def test_pathed_lazyload_aliased_abs_bcs(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- opt = Load(A).joinedload(A.bs).joinedload(B.cs)
- q = (
- s.query(aa, A)
- .filter(aa.id == 1)
- .filter(A.id == 2)
- .filter(aa.id != A.id)
- .options(opt)
- )
- self._run_tests(q, 3)
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ opt = Load(A).joinedload(A.bs).joinedload(B.cs)
+
+ q = (
+ s.query(aa, A)
+ .filter(aa.id == 1)
+ .filter(A.id == 2)
+ .filter(aa.id != A.id)
+ .options(opt)
+ )
+ self._run_tests(q, 3)
def test_pathed_lazyload_plus_joined_aliased_abs_bcs(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- opt = Load(aa).defaultload(aa.bs).joinedload(B.cs)
- q = (
- s.query(aa, A)
- .filter(aa.id == 1)
- .filter(A.id == 2)
- .filter(aa.id != A.id)
- .options(opt)
- )
- self._run_tests(q, 2)
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ opt = Load(aa).defaultload(aa.bs).joinedload(B.cs)
+
+ q = (
+ s.query(aa, A)
+ .filter(aa.id == 1)
+ .filter(A.id == 2)
+ .filter(aa.id != A.id)
+ .options(opt)
+ )
+ self._run_tests(q, 2)
def test_pathed_joinedload_aliased_abs_bcs(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- opt = Load(aa).joinedload(aa.bs).joinedload(B.cs)
- q = (
- s.query(aa, A)
- .filter(aa.id == 1)
- .filter(A.id == 2)
- .filter(aa.id != A.id)
- .options(opt)
- )
- self._run_tests(q, 1)
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ opt = Load(aa).joinedload(aa.bs).joinedload(B.cs)
+
+ q = (
+ s.query(aa, A)
+ .filter(aa.id == 1)
+ .filter(A.id == 2)
+ .filter(aa.id != A.id)
+ .options(opt)
+ )
+ self._run_tests(q, 1)
def test_lazyload_plus_joined_aliased_abs_bcs(self):
+ """by running the test twice, this test includes a test
+ for #7447 to ensure cached queries apply the cached option objects
+ to the InstanceState which line up with the cached current_path."""
+
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(aa, A)
- .filter(aa.id == 1)
- .filter(A.id == 2)
- .filter(aa.id != A.id)
- .options(defaultload(aa.bs).joinedload(B.cs))
- )
- self._run_tests(q, 2)
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(aa, A)
+ .filter(aa.id == 1)
+ .filter(A.id == 2)
+ .filter(aa.id != A.id)
+ .options(defaultload(aa.bs).joinedload(B.cs))
+ )
+
+ self._run_tests(q, 2)
def test_joinedload_aliased_abs_bcs(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(aa, A)
- .filter(aa.id == 1)
- .filter(A.id == 2)
- .filter(aa.id != A.id)
- .options(joinedload(aa.bs).joinedload(B.cs))
- )
- self._run_tests(q, 1)
+
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(aa, A)
+ .filter(aa.id == 1)
+ .filter(A.id == 2)
+ .filter(aa.id != A.id)
+ .options(joinedload(aa.bs).joinedload(B.cs))
+ )
+ self._run_tests(q, 1)
def test_lazyload_unaliased_abs_bcs_one(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(A, aa)
- .filter(aa.id == 2)
- .filter(A.id == 1)
- .filter(aa.id != A.id)
- .options(joinedload(aa.bs).joinedload(B.cs))
- )
- self._run_tests(q, 3)
+
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(A, aa)
+ .filter(aa.id == 2)
+ .filter(A.id == 1)
+ .filter(aa.id != A.id)
+ .options(joinedload(aa.bs).joinedload(B.cs))
+ )
+ self._run_tests(q, 3)
def test_lazyload_unaliased_abs_bcs_two(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(A, aa)
- .filter(aa.id == 2)
- .filter(A.id == 1)
- .filter(aa.id != A.id)
- .options(defaultload(aa.bs).joinedload(B.cs))
- )
- self._run_tests(q, 3)
+
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(A, aa)
+ .filter(aa.id == 2)
+ .filter(A.id == 1)
+ .filter(aa.id != A.id)
+ .options(defaultload(aa.bs).joinedload(B.cs))
+ )
+ self._run_tests(q, 3)
def test_lazyload_plus_joined_unaliased_abs_bcs(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(A, aa)
- .filter(aa.id == 2)
- .filter(A.id == 1)
- .filter(aa.id != A.id)
- .options(defaultload(A.bs).joinedload(B.cs))
- )
- self._run_tests(q, 2)
+
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(A, aa)
+ .filter(aa.id == 2)
+ .filter(A.id == 1)
+ .filter(aa.id != A.id)
+ .options(defaultload(A.bs).joinedload(B.cs))
+ )
+ self._run_tests(q, 2)
def test_joinedload_unaliased_abs_bcs(self):
A, B, C = self.classes("A", "B", "C")
- s = fixture_session()
- aa = aliased(A)
- q = (
- s.query(A, aa)
- .filter(aa.id == 2)
- .filter(A.id == 1)
- .filter(aa.id != A.id)
- .options(joinedload(A.bs).joinedload(B.cs))
- )
- self._run_tests(q, 1)
+
+ for i in range(2):
+ s = fixture_session()
+ aa = aliased(A)
+ q = (
+ s.query(A, aa)
+ .filter(aa.id == 2)
+ .filter(A.id == 1)
+ .filter(aa.id != A.id)
+ .options(joinedload(A.bs).joinedload(B.cs))
+ )
+ self._run_tests(q, 1)
class EntityViaMultiplePathTestThree(fixtures.DeclarativeMappedTest):