summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-05-12 10:53:54 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-05-12 10:53:54 -0400
commit0f8721fa52e335ab2abeb548c8914b99a8c5e1fd (patch)
tree1a286f7c2199e5c54c4fbac26187c6821fa7b9b3 /lib/sqlalchemy/orm
parent4352e220ac04d09e120c441e79b1ac12c7ca2c45 (diff)
downloadsqlalchemy-0f8721fa52e335ab2abeb548c8914b99a8c5e1fd.tar.gz
Cascade mappers in terms of the instance's mapper
Fixed a (extremely old) bug in cascade_mappers where the first cascade we do is against the "self" mapper, and not the one that actually corresponds to the state given. These are different in the case where we start with a relationship to a class, and the instance is of a subclass, which itself can have relationships that aren't on the base mapper. A pretty severe bug that somehow has avoided the radar since the beginning. Change-Id: I512956b9757b07e06f3ca1ccb507a33fb10bed31 Fixes: #3986
Diffstat (limited to 'lib/sqlalchemy/orm')
-rw-r--r--lib/sqlalchemy/orm/mapper.py14
1 files changed, 10 insertions, 4 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 3fdba4482..61a9290c4 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -2689,7 +2689,9 @@ class Mapper(InspectionAttr):
visited_states = set()
prp, mpp = object(), object()
- visitables = deque([(deque(self._props.values()), prp,
+ assert state.mapper.isa(self)
+
+ visitables = deque([(deque(state.mapper._props.values()), prp,
state, state.dict)])
while visitables:
@@ -2712,9 +2714,13 @@ class Mapper(InspectionAttr):
corresponding_dict = iterator.popleft()
yield instance, instance_mapper, \
corresponding_state, corresponding_dict
- visitables.append((deque(instance_mapper._props.values()),
- prp, corresponding_state,
- corresponding_dict))
+ visitables.append(
+ (
+ deque(instance_mapper._props.values()),
+ prp, corresponding_state,
+ corresponding_dict
+ )
+ )
@_memoized_configured_property
def _compiled_cache(self):