diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2017-11-03 11:11:48 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2017-12-04 17:35:40 -0500 |
| commit | 8ab652c6cb48ca6e157233aa3a23049e318d9d2b (patch) | |
| tree | 668c42f0af5039080120bf31951ca1f4c29b8dc8 /lib/sqlalchemy | |
| parent | bcbff960a17654004a08401546d8c2d990ee9894 (diff) | |
| download | sqlalchemy-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.py | 25 |
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"}, |
