summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2020-01-30 16:15:56 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2020-01-30 16:15:56 +0000
commit237724d338bf8fd88a24f2bb9dd0c800bda7dbde (patch)
tree04d126116fb6b48691a9996721d922953ba95a61 /lib/sqlalchemy
parent447dec2c15f7b749a3e98df93c001b1b9a36ed32 (diff)
parentc741b89bd57eb31b7a1bbd187a4d159bdfea5111 (diff)
downloadsqlalchemy-237724d338bf8fd88a24f2bb9dd0c800bda7dbde.tar.gz
Merge "Raise for unexpected polymorphic identity"
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/loading.py40
-rw-r--r--lib/sqlalchemy/orm/query.py8
2 files changed, 37 insertions, 11 deletions
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index b823de4ab..218449cdd 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -643,11 +643,9 @@ def _instance_processor(
identity_token,
)
if not is_not_primary_key(identitykey[1]):
- raise sa_exc.InvalidRequestError(
- "Row with identity key %s can't be loaded into an "
- "object; the polymorphic discriminator column '%s' is "
- "NULL" % (identitykey, polymorphic_discriminator)
- )
+ return identitykey
+ else:
+ return None
_instance = _decorate_polymorphic_switch(
_instance,
@@ -843,6 +841,8 @@ def _decorate_polymorphic_switch(
else:
if sub_mapper is mapper:
return None
+ elif not sub_mapper.isa(mapper):
+ return False
return _instance_processor(
sub_mapper,
@@ -863,11 +863,37 @@ def _decorate_polymorphic_switch(
_instance = polymorphic_instances[discriminator]
if _instance:
return _instance(row)
+ elif _instance is False:
+ identitykey = ensure_no_pk(row)
+
+ if identitykey:
+ raise sa_exc.InvalidRequestError(
+ "Row with identity key %s can't be loaded into an "
+ "object; the polymorphic discriminator column '%s' "
+ "refers to %s, which is not a sub-mapper of "
+ "the requested %s"
+ % (
+ identitykey,
+ polymorphic_on,
+ mapper.polymorphic_map[discriminator],
+ mapper,
+ )
+ )
+ else:
+ return None
else:
return instance_fn(row)
else:
- ensure_no_pk(row)
- return None
+ identitykey = ensure_no_pk(row)
+
+ if identitykey:
+ raise sa_exc.InvalidRequestError(
+ "Row with identity key %s can't be loaded into an "
+ "object; the polymorphic discriminator column '%s' is "
+ "NULL" % (identitykey, polymorphic_on)
+ )
+ else:
+ return None
return polymorphic_instance
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 55b569bcd..15319e049 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -260,6 +260,7 @@ class Query(Generative):
self._from_obj_alias = sql_util.ColumnAdapter(
self._from_obj[0], equivs
)
+ self._enable_single_crit = False
elif (
set_base_alias
and len(self._from_obj) == 1
@@ -267,6 +268,7 @@ class Query(Generative):
and info.is_aliased_class
):
self._from_obj_alias = info._adapter
+ self._enable_single_crit = False
def _reset_polymorphic_adapter(self, mapper):
for m2 in mapper._with_polymorphic_mappers:
@@ -1379,7 +1381,6 @@ class Query(Generative):
._anonymous_fromclause()
)
q = self._from_selectable(fromclause)
- q._enable_single_crit = False
q._select_from_entity = self._entity_zero()
if entities:
q._set_entities(entities)
@@ -1407,6 +1408,7 @@ class Query(Generative):
):
self.__dict__.pop(attr, None)
self._set_select_from([fromclause], True)
+ self._enable_single_crit = False
# this enables clause adaptation for non-ORM
# expressions.
@@ -1875,9 +1877,7 @@ class Query(Generative):
self._having = criterion
def _set_op(self, expr_fn, *q):
- return self._from_selectable(
- expr_fn(*([self] + list(q))).subquery()
- )._set_enable_single_crit(False)
+ return self._from_selectable(expr_fn(*([self] + list(q))).subquery())
def union(self, *q):
"""Produce a UNION of this Query against one or more queries.