diff options
author | mike bayer <mike_mp@zzzcomputing.com> | 2020-01-30 16:15:56 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2020-01-30 16:15:56 +0000 |
commit | 237724d338bf8fd88a24f2bb9dd0c800bda7dbde (patch) | |
tree | 04d126116fb6b48691a9996721d922953ba95a61 /lib/sqlalchemy | |
parent | 447dec2c15f7b749a3e98df93c001b1b9a36ed32 (diff) | |
parent | c741b89bd57eb31b7a1bbd187a4d159bdfea5111 (diff) | |
download | sqlalchemy-237724d338bf8fd88a24f2bb9dd0c800bda7dbde.tar.gz |
Merge "Raise for unexpected polymorphic identity"
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r-- | lib/sqlalchemy/orm/loading.py | 40 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/query.py | 8 |
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. |