diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/orm/__init__.py | 1 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 36 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/fixtures.py | 5 |
3 files changed, 26 insertions, 16 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index a247b597b..8e9647840 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -44,6 +44,7 @@ from .interfaces import MapperProperty from .interfaces import NOT_EXTENSION from .interfaces import ONETOMANY from .interfaces import PropComparator +from .interfaces import UserDefinedOption from .loading import merge_frozen_result from .loading import merge_result from .mapper import class_mapper diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index bf60c803d..069e5e667 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -1512,21 +1512,14 @@ class SubqueryLoader(PostLoader): loadopt, ): - if orig_query is context.query: - options = new_options = orig_query._with_options - else: - # There's currently no test that exercises the necessity of - # this step for subqueryload. Added in #6881, it is necessary for - # selectinload, but its necessity for subqueryload is still - # theoretical. - options = orig_query._with_options - - new_options = [ - orig_opt._adjust_for_extra_criteria(context) - if orig_opt._is_strategy_option - else orig_opt - for orig_opt in options - ] + # note that because the subqueryload object + # does not re-use the cached query, instead always making + # use of the current invoked query, while we have two queries + # here (orig and context.query), they are both non-cached + # queries and we can transfer the options as is without + # adjusting for new criteria. Some work on #6881 / #6889 + # brought this into question. + new_options = orig_query._with_options if loadopt and loadopt._extra_criteria: @@ -2933,9 +2926,12 @@ class SelectInLoader(PostLoader, util.MemoizedSlots): if orig_query is context.query: options = new_options = orig_query._with_options + user_defined_options = [] else: options = orig_query._with_options + # propagate compile state options from the original query, + # updating their "extra_criteria" as necessary. # note this will create a different cache key than # "orig" options if extra_criteria is present, because the copy # of extra_criteria will have different boundparam than that of @@ -2946,6 +2942,14 @@ class SelectInLoader(PostLoader, util.MemoizedSlots): if orig_opt._is_strategy_option else orig_opt for orig_opt in options + if orig_opt._is_compile_state or orig_opt._is_legacy_option + ] + + # propagate user defined options from the current query + user_defined_options = [ + opt + for opt in context.query._with_options + if not opt._is_compile_state and not opt._is_legacy_option ] if loadopt and loadopt._extra_criteria: @@ -2959,6 +2963,8 @@ class SelectInLoader(PostLoader, util.MemoizedSlots): q = q.options(*new_options)._update_compile_options( {"_current_path": effective_path} ) + if user_defined_options: + q = q.options(*user_defined_options) if context.populate_existing: q = q.execution_options(populate_existing=True) diff --git a/lib/sqlalchemy/testing/fixtures.py b/lib/sqlalchemy/testing/fixtures.py index 30ada71cd..e6af0c546 100644 --- a/lib/sqlalchemy/testing/fixtures.py +++ b/lib/sqlalchemy/testing/fixtures.py @@ -548,7 +548,10 @@ _fixture_sessions = set() def fixture_session(**kw): kw.setdefault("autoflush", True) kw.setdefault("expire_on_commit", True) - sess = sa.orm.Session(config.db, **kw) + + bind = kw.pop("bind", config.db) + + sess = sa.orm.Session(bind, **kw) _fixture_sessions.add(sess) return sess |
