From 54db0518b0fe7a4a0b7d03b83aed6e7b6fa12e1b Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 4 Dec 2022 12:02:37 -0500 Subject: Add tests for issue #8168; slight internal adjustments The issue in #8168 was improved, but not completely fixed, by #8456. This includes some small changes to ORM context that are a prerequisite for getting ORM adaptation to be better. Have these in 2.0.0b4 so that we have at least a better starting point. References: #8168 Change-Id: I51dbe333b156048836d074fbba1d850f9eb67fd2 --- lib/sqlalchemy/orm/context.py | 14 +++++--------- lib/sqlalchemy/orm/util.py | 9 ++++++++- lib/sqlalchemy/sql/util.py | 1 - 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py index 621b3e5d7..b5b326bca 100644 --- a/lib/sqlalchemy/orm/context.py +++ b/lib/sqlalchemy/orm/context.py @@ -520,13 +520,16 @@ class ORMCompileState(AbstractORMCompileState): for mp in ext_info.mapper.iterate_to_root(): self._mapper_loads_polymorphically_with( mp, - sql_util.ColumnAdapter(selectable, mp._equivalent_columns), + ORMAdapter( + mp, mp._equivalent_columns, selectable=selectable + ), ) def _mapper_loads_polymorphically_with(self, mapper, adapter): for m2 in mapper._with_polymorphic_mappers or [mapper]: self._polymorphic_adapters[m2] = adapter - for m in m2.iterate_to_root(): # TODO: redundant ? + + for m in m2.iterate_to_root(): self._polymorphic_adapters[m.local_table] = adapter @classmethod @@ -1673,13 +1676,6 @@ class ORMSelectCompileState(ORMCompileState, SelectState): left = onclause._parententity - alias = self._polymorphic_adapters.get(left, None) - - # could be None or could be ColumnAdapter also - if isinstance(alias, ORMAdapter) and alias.mapper.isa(left): - left = alias.aliased_class - onclause = getattr(left, onclause.key) - prop = onclause.property if not isinstance(onclause, attributes.QueryableAttribute): onclause = prop diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index c0fc11d23..6ed8e2272 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -107,6 +107,7 @@ if typing.TYPE_CHECKING: from ..sql.selectable import _ColumnsClauseElement from ..sql.selectable import Alias from ..sql.selectable import Select + from ..sql.selectable import Selectable from ..sql.selectable import Subquery from ..sql.visitors import anon_map from ..util.typing import _AnnotationScanType @@ -456,10 +457,12 @@ class ORMAdapter(sql_util.ColumnAdapter): adapt_required: bool = False, allow_label_resolve: bool = True, anonymize_labels: bool = False, + selectable: Optional[Selectable] = None, ): self.mapper = entity.mapper - selectable = entity.selectable + if selectable is None: + selectable = entity.selectable if insp_is_aliased_class(entity): self.is_aliased_class = True self.aliased_insp = entity @@ -478,6 +481,10 @@ class ORMAdapter(sql_util.ColumnAdapter): ) def _include_fn(self, elem): + # TODO: we still have cases where we should return False here + # yet we are not able to reliably detect without false positives. + # see issue #8168 + entity = elem._annotations.get("parentmapper", None) return not entity or entity.isa(self.mapper) or self.mapper.isa(entity) diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 14cbe2456..d162428ec 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -1139,7 +1139,6 @@ class ClauseAdapter(visitors.ReplacingExternalTraversal): if isinstance(col, FromClause) and not isinstance( col, functions.FunctionElement ): - if self.selectable.is_derived_from(col): if self.adapt_from_selectables: for adp in self.adapt_from_selectables: -- cgit v1.2.1