summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-11-03 11:11:48 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-12-04 17:35:40 -0500
commit8ab652c6cb48ca6e157233aa3a23049e318d9d2b (patch)
tree668c42f0af5039080120bf31951ca1f4c29b8dc8 /lib/sqlalchemy
parentbcbff960a17654004a08401546d8c2d990ee9894 (diff)
downloadsqlalchemy-8ab652c6cb48ca6e157233aa3a23049e318d9d2b.tar.gz
Intercept contains_eager() with of_type, set aliased / polymorphic
Fixed bug in :func:`.contains_eager` query option where making use of a path that used :meth:`.PropComparator.of_type` to refer to a subclass across more than one level of joins would also require that the "alias" argument were provided with the same subtype in order to avoid adding unwanted FROM clauses to the query; additionally, using :func:`.contains_eager` across subclasses that use :func:`.aliased` objects of subclasses as the :meth:`.PropComparator.of_type` argument will also render correctly. Change-Id: Ie1c10924faa45251aab1a076a3ba7ef9fb1bdeee Fixes: #4130
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/strategy_options.py25
1 files changed, 22 insertions, 3 deletions
diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py
index 86a48f3b9..775ed6c97 100644
--- a/lib/sqlalchemy/orm/strategy_options.py
+++ b/lib/sqlalchemy/orm/strategy_options.py
@@ -211,7 +211,7 @@ class Load(Generative, MapperOption):
if getattr(attr, '_of_type', None):
ac = attr._of_type
- ext_info = inspect(ac)
+ ext_info = of_type_info = inspect(ac)
existing = path.entity_path[prop].get(
self.context, "path_with_polymorphic")
@@ -221,8 +221,23 @@ class Load(Generative, MapperOption):
ext_info.mapper, aliased=True,
_use_mapper_path=True,
_existing_alias=existing)
+ ext_info = inspect(ac)
+ elif not ext_info.with_polymorphic_mappers:
+ ext_info = orm_util.AliasedInsp(
+ ext_info.entity,
+ ext_info.mapper.base_mapper,
+ ext_info.selectable,
+ ext_info.name,
+ ext_info.with_polymorphic_mappers or [ext_info.mapper],
+ ext_info.polymorphic_on,
+ ext_info._base_alias,
+ ext_info._use_mapper_path,
+ ext_info._adapt_on_names,
+ ext_info.represents_outer_join
+ )
+
path.entity_path[prop].set(
- self.context, "path_with_polymorphic", inspect(ac))
+ self.context, "path_with_polymorphic", ext_info)
# the path here will go into the context dictionary and
# needs to match up to how the class graph is traversed.
@@ -235,7 +250,7 @@ class Load(Generative, MapperOption):
# it might be better for "path" to really represent,
# "the path", but trying to keep the impact of the cache
# key feature localized for now
- self._of_type = ext_info
+ self._of_type = of_type_info
else:
path = path[prop]
@@ -787,6 +802,10 @@ def contains_eager(loadopt, attr, alias=None):
info = inspect(alias)
alias = info.selectable
+ elif getattr(attr, '_of_type', None):
+ ot = inspect(attr._of_type)
+ alias = ot.selectable
+
cloned = loadopt.set_relationship_strategy(
attr,
{"lazy": "joined"},