From 04421c8bed9e93a625b7164e99eb1ee0395bebfe Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 12 Dec 2021 13:37:21 -0500 Subject: use the options from the cached statement for propagate_options Fixed caching-related issue where the use of a loader option of the form ``lazyload(aliased(A).bs).joinedload(B.cs)`` would fail to result in the joinedload being invoked for runs subsequent to the query being cached, due to a mismatch for the options / object path applied to the objects loaded for a query with a lead entity that used ``aliased()``. Fixes: #7447 Change-Id: I4e9c34654b7d3668cd8878decbd688afe2af5f81 --- lib/sqlalchemy/orm/context.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'lib/sqlalchemy/orm/context.py') diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py index 8e3dc3134..61b957280 100644 --- a/lib/sqlalchemy/orm/context.py +++ b/lib/sqlalchemy/orm/context.py @@ -106,7 +106,27 @@ class QueryContext: 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) -- cgit v1.2.1