summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-09-30 21:26:08 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-10-01 16:11:34 -0400
commit9a2a0f324c13b5a1b334a3982a766cb9f21f428e (patch)
treef4548faa2cf60f07d2e13e6eb1b137ff1d3e072d /lib/sqlalchemy
parenta3c964203e61f8deeb559b15a78cc640dee67012 (diff)
downloadsqlalchemy-9a2a0f324c13b5a1b334a3982a766cb9f21f428e.tar.gz
Cancel polymorphic loading in optimized get
Since optimized_get for inheriting mappers writes a simple SELECT, we need to cancel out any with_polymorphic selectables that interfere with simple column lookup. While adaptation is another option, just removing the with_polymorphic is much simpler. The issue is not noticeable unless the ResultProxy is not allowing "key fallback" column lookups, which will be the case when this behavior is deprecated. Fixes: #4718 Change-Id: I8fa2f5c0434b6a681813a92ac71fe12712f5d634
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/loading.py7
-rw-r--r--lib/sqlalchemy/orm/query.py5
-rw-r--r--lib/sqlalchemy/orm/strategies.py1
-rw-r--r--lib/sqlalchemy/sql/util.py2
4 files changed, 11 insertions, 4 deletions
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index 94a9b8d22..886240591 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -23,6 +23,7 @@ from . import strategy_options
from .base import _DEFER_FOR_STATE
from .base import _SET_DEFERRED_EXPIRED
from .util import _none_set
+from .util import aliased
from .util import state_str
from .. import exc as sa_exc
from .. import util
@@ -633,7 +634,6 @@ def _instance_processor(
if mapper.polymorphic_map and not _polymorphic_from and not refresh_state:
# if we are doing polymorphic, dispatch to a different _instance()
# method specific to the subclass mapper
-
def ensure_no_pk(row):
identitykey = (
identity_class,
@@ -957,9 +957,10 @@ def load_scalar_attributes(mapper, state, attribute_names):
# by default
statement = mapper._optimized_get_statement(state, attribute_names)
if statement is not None:
+ wp = aliased(mapper, statement)
result = load_on_ident(
- session.query(mapper)
- .options(strategy_options.Load(mapper).undefer("*"))
+ session.query(wp)
+ .options(strategy_options.Load(wp).undefer("*"))
.from_statement(statement),
None,
only_load_props=attribute_names,
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 3d08dce22..0480bfb01 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -774,6 +774,11 @@ class Query(Generative):
)
entity = self._entities[0]._clone()
self._entities = [entity] + self._entities[1:]
+
+ # NOTE: we likely should set primary_entity here, however
+ # this hasn't been changed for many years and we'd like to
+ # deprecate this method.
+
entity.set_with_polymorphic(
self,
cls_or_mappers,
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 1f2f65728..1c7c0546d 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -183,7 +183,6 @@ class ColumnLoader(LoaderStrategy):
memoized_populators,
**kwargs
):
-
for c in self.columns:
if adapter:
c = adapter.columns[c]
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py
index 3c7f904de..780cdc7b2 100644
--- a/lib/sqlalchemy/sql/util.py
+++ b/lib/sqlalchemy/sql/util.py
@@ -798,6 +798,8 @@ class ClauseAdapter(visitors.ReplacingCloningVisitor):
if newcol is not None:
return newcol
if self.adapt_on_names and newcol is None:
+ # TODO: this should be changed to .exported_columns if and
+ # when we need to be able to adapt a plain Select statement
newcol = self.selectable.c.get(col.name)
return newcol