summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/loading.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-09-03 09:56:41 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-09-03 22:20:15 -0400
commitc3dcdbd21de44b23e527f5580c318e47ea6930a7 (patch)
treed180fa6afd22e6d09e27cf7c4d710c8177549557 /lib/sqlalchemy/orm/loading.py
parent43e0d7c06ba154e806a72d72ad06ae56a32225aa (diff)
downloadsqlalchemy-c3dcdbd21de44b23e527f5580c318e47ea6930a7.tar.gz
Raise for NULL discriminator and pk is present
An exception is now raised if the ORM loads a row for a polymorphic instance that has a primary key but the discriminator column is NULL, as discriminator columns should not be null. Fixes: #4836 Change-Id: Ice1a853a7dd7687c58079b9933f145b90d314236
Diffstat (limited to 'lib/sqlalchemy/orm/loading.py')
-rw-r--r--lib/sqlalchemy/orm/loading.py22
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index f07067d17..94a9b8d22 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -633,6 +633,20 @@ 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,
+ tuple([row[column] for column in pk_cols]),
+ 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)
+ )
+
_instance = _decorate_polymorphic_switch(
_instance,
context,
@@ -641,6 +655,7 @@ def _instance_processor(
path,
polymorphic_discriminator,
adapter,
+ ensure_no_pk,
)
return _instance
@@ -804,6 +819,7 @@ def _decorate_polymorphic_switch(
path,
polymorphic_discriminator,
adapter,
+ ensure_no_pk,
):
if polymorphic_discriminator is not None:
polymorphic_on = polymorphic_discriminator
@@ -843,7 +859,11 @@ def _decorate_polymorphic_switch(
_instance = polymorphic_instances[discriminator]
if _instance:
return _instance(row)
- return instance_fn(row)
+ else:
+ return instance_fn(row)
+ else:
+ ensure_no_pk(row)
+ return None
return polymorphic_instance