summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-01-20 12:41:22 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-01-20 16:25:33 -0500
commit20e14633fb15018ccf1f5d127fd67609bfe2b3e5 (patch)
treeae05d084bd39b1020eaabd2a8a4c8da868cda6a5 /lib/sqlalchemy
parentd8ac1e9e6bfc931d2f14f9846d6924106f56b7e6 (diff)
downloadsqlalchemy-20e14633fb15018ccf1f5d127fd67609bfe2b3e5.tar.gz
Adjust natural path to relationship's base mapper for aliased class also
Fixed regression in loader options introduced in 1.3.0b3 via :ticket:`4468` where the ability to create a loader option using :meth:`.PropComparator.of_type` targeting an aliased entity that is an inheriting subclass of the entity which the preceding relationship refers to would fail to produce a matching path. See also :ticket:`5082` fixed in this same release which involves a similar kind of issue. Fixes: #5107 Change-Id: I5c6717b925060c3f8da42190d1f00d05248befd8
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/path_registry.py96
1 files changed, 53 insertions, 43 deletions
diff --git a/lib/sqlalchemy/orm/path_registry.py b/lib/sqlalchemy/orm/path_registry.py
index 2df1b3b4c..2c0847426 100644
--- a/lib/sqlalchemy/orm/path_registry.py
+++ b/lib/sqlalchemy/orm/path_registry.py
@@ -250,51 +250,61 @@ class PropRegistry(PathRegistry):
# given MapperProperty's parent.
insp = inspection.inspect(parent[-1])
natural_parent = parent
+
if not insp.is_aliased_class or insp._use_mapper_path:
parent = natural_parent = parent.parent[prop.parent]
- elif insp.is_aliased_class and insp.with_polymorphic_mappers:
- if (
- prop.parent is not insp.mapper
- and prop.parent in insp.with_polymorphic_mappers
- ):
- subclass_entity = parent[-1]._entity_for_mapper(prop.parent)
- parent = parent.parent[subclass_entity]
-
- # when building a path where with_polymorphic() is in use,
- # special logic to determine the "natural path" when subclass
- # entities are used.
- #
- # here we are trying to distinguish between a path that starts
- # on a the with_polymorhpic entity vs. one that starts on a
- # normal entity that introduces a with_polymorphic() in the
- # middle using of_type():
- #
- # # as in test_polymorphic_rel->
- # # test_subqueryload_on_subclass_uses_path_correctly
- # wp = with_polymorphic(RegularEntity, "*")
- # sess.query(wp).options(someload(wp.SomeSubEntity.foos))
- #
- # vs
- #
- # # as in test_relationship->JoinedloadWPolyOfTypeContinued
- # wp = with_polymorphic(SomeFoo, "*")
- # sess.query(RegularEntity).options(
- # someload(RegularEntity.foos.of_type(wp))
- # .someload(wp.SubFoo.bar)
- # )
- #
- # in the former case, the Query as it generates a path that we
- # want to match will be in terms of the with_polymorphic at the
- # beginning. in the latter case, Query will generate simple
- # paths that don't know about this with_polymorphic, so we must
- # use a separate natural path.
- #
- #
- if parent.parent:
- natural_parent = parent.parent[subclass_entity.mapper]
- self.is_unnatural = True
- else:
- natural_parent = parent
+ elif (
+ insp.is_aliased_class
+ and insp.with_polymorphic_mappers
+ and prop.parent is not insp.mapper
+ and prop.parent in insp.with_polymorphic_mappers
+ ):
+ subclass_entity = parent[-1]._entity_for_mapper(prop.parent)
+ parent = parent.parent[subclass_entity]
+
+ # when building a path where with_polymorphic() is in use,
+ # special logic to determine the "natural path" when subclass
+ # entities are used.
+ #
+ # here we are trying to distinguish between a path that starts
+ # on a the with_polymorhpic entity vs. one that starts on a
+ # normal entity that introduces a with_polymorphic() in the
+ # middle using of_type():
+ #
+ # # as in test_polymorphic_rel->
+ # # test_subqueryload_on_subclass_uses_path_correctly
+ # wp = with_polymorphic(RegularEntity, "*")
+ # sess.query(wp).options(someload(wp.SomeSubEntity.foos))
+ #
+ # vs
+ #
+ # # as in test_relationship->JoinedloadWPolyOfTypeContinued
+ # wp = with_polymorphic(SomeFoo, "*")
+ # sess.query(RegularEntity).options(
+ # someload(RegularEntity.foos.of_type(wp))
+ # .someload(wp.SubFoo.bar)
+ # )
+ #
+ # in the former case, the Query as it generates a path that we
+ # want to match will be in terms of the with_polymorphic at the
+ # beginning. in the latter case, Query will generate simple
+ # paths that don't know about this with_polymorphic, so we must
+ # use a separate natural path.
+ #
+ #
+ if parent.parent:
+ natural_parent = parent.parent[subclass_entity.mapper]
+ self.is_unnatural = True
+ else:
+ natural_parent = parent
+ elif (
+ natural_parent.parent
+ and insp.is_aliased_class
+ and prop.parent # this should always be the case here
+ is not insp.mapper
+ and insp.mapper.isa(prop.parent)
+ ):
+ natural_parent = parent.parent[prop.parent]
self.prop = prop
self.parent = parent