summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/loading.py
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2023-02-27 15:30:35 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2023-02-27 15:30:35 +0000
commit1cce6265a700aee986d6a3421eb3622db32f0c45 (patch)
tree7f3319d2670bb63600c33bb895e40eaf96aea797 /lib/sqlalchemy/orm/loading.py
parentc76f5933735ab19f5e409d1dd25aafe0e4fa399b (diff)
parent40b00498e62d3bf10f75874852bab6d6e0e3a09a (diff)
downloadsqlalchemy-1cce6265a700aee986d6a3421eb3622db32f0c45.tar.gz
Merge "include columns from superclasses that indicate "selectin"" into main
Diffstat (limited to 'lib/sqlalchemy/orm/loading.py')
-rw-r--r--lib/sqlalchemy/orm/loading.py54
1 files changed, 42 insertions, 12 deletions
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index 54b96c215..7974d94c5 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -972,17 +972,17 @@ def _instance_processor(
if not refresh_state and _polymorphic_from is not None:
key = ("loader", path.path)
+
if key in context.attributes and context.attributes[key].strategy == (
("selectinload_polymorphic", True),
):
- selectin_load_via = mapper._should_selectin_load(
- context.attributes[key].local_opts["entities"],
- _polymorphic_from,
- )
+ option_entities = context.attributes[key].local_opts["entities"]
else:
- selectin_load_via = mapper._should_selectin_load(
- None, _polymorphic_from
- )
+ option_entities = None
+ selectin_load_via = mapper._should_selectin_load(
+ option_entities,
+ _polymorphic_from,
+ )
if selectin_load_via and selectin_load_via is not _polymorphic_from:
# only_load_props goes w/ refresh_state only, and in a refresh
@@ -990,8 +990,13 @@ def _instance_processor(
# loading does not apply
assert only_load_props is None
- callable_ = _load_subclass_via_in(context, path, selectin_load_via)
-
+ callable_ = _load_subclass_via_in(
+ context,
+ path,
+ selectin_load_via,
+ _polymorphic_from,
+ option_entities,
+ )
PostLoad.callable_for_path(
context,
load_path,
@@ -1212,17 +1217,42 @@ def _instance_processor(
return _instance
-def _load_subclass_via_in(context, path, entity):
+def _load_subclass_via_in(
+ context, path, entity, polymorphic_from, option_entities
+):
mapper = entity.mapper
+ # TODO: polymorphic_from seems to be a Mapper in all cases.
+ # this is likely not needed, but as we dont have typing in loading.py
+ # yet, err on the safe side
+ polymorphic_from_mapper = polymorphic_from.mapper
+ not_against_basemost = polymorphic_from_mapper.inherits is not None
+
zero_idx = len(mapper.base_mapper.primary_key) == 1
- if entity.is_aliased_class:
- q, enable_opt, disable_opt = mapper._subclass_load_via_in(entity)
+ if entity.is_aliased_class or not_against_basemost:
+ q, enable_opt, disable_opt = mapper._subclass_load_via_in(
+ entity, polymorphic_from
+ )
else:
q, enable_opt, disable_opt = mapper._subclass_load_via_in_mapper
def do_load(context, path, states, load_only, effective_entity):
+ if not option_entities:
+ # filter out states for those that would have selectinloaded
+ # from another loader
+ # TODO: we are currently ignoring the case where the
+ # "selectin_polymorphic" option is used, as this is much more
+ # complex / specific / very uncommon API use
+ states = [
+ (s, v)
+ for s, v in states
+ if s.mapper._would_selectin_load_only_from_given_mapper(mapper)
+ ]
+
+ if not states:
+ return
+
orig_query = context.query
options = (enable_opt,) + orig_query._with_options + (disable_opt,)