diff options
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/ext/mutable.py | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py index 4bb9e795b..fef886501 100644 --- a/lib/sqlalchemy/ext/mutable.py +++ b/lib/sqlalchemy/ext/mutable.py @@ -357,10 +357,10 @@ pickling process of the parent's object-relational state so that the import weakref from .. import event +from .. import inspect from .. import types from ..orm import Mapper from ..orm import mapper -from ..orm import object_mapper from ..orm.attributes import flag_modified from ..sql.base import SchemaEventTarget from ..util import memoized_property @@ -374,12 +374,17 @@ class MutableBase(object): @memoized_property def _parents(self): - """Dictionary of parent object->attribute name on the parent. + """Dictionary of parent object's :class:`.InstanceState`->attribute + name on the parent. This attribute is a so-called "memoized" property. It initializes itself with a new ``weakref.WeakKeyDictionary`` the first time it is accessed, returning the same object upon subsequent access. + .. versionchanged:: 1.4 the :class:`.InstanceState` is now used + as the key in the weak dictionary rather than the instance + itself. + """ return weakref.WeakKeyDictionary() @@ -461,7 +466,7 @@ class MutableBase(object): if coerce: val = cls.coerce(key, val) state.dict[key] = val - val._parents[state.obj()] = key + val._parents[state] = key def load_attrs(state, ctx, attrs): if not attrs or listen_keys.intersection(attrs): @@ -482,9 +487,9 @@ class MutableBase(object): if not isinstance(value, cls): value = cls.coerce(key, value) if value is not None: - value._parents[target.obj()] = key + value._parents[target] = key if isinstance(oldvalue, cls): - oldvalue._parents.pop(target.obj(), None) + oldvalue._parents.pop(inspect(target), None) return value def pickle(state, state_dict): @@ -497,7 +502,7 @@ class MutableBase(object): def unpickle(state, state_dict): if "ext.mutable.values" in state_dict: for val in state_dict["ext.mutable.values"]: - val._parents[state.obj()] = key + val._parents[state] = key event.listen(parent_cls, "load", load, raw=True, propagate=True) event.listen( @@ -527,7 +532,7 @@ class Mutable(MutableBase): """Subclasses should call this method whenever change events occur.""" for parent, key in self._parents.items(): - flag_modified(parent, key) + flag_modified(parent.obj(), key) @classmethod def associate_with_attribute(cls, attribute): @@ -647,11 +652,11 @@ class MutableComposite(MutableBase): for parent, key in self._parents.items(): - prop = object_mapper(parent).get_property(key) + prop = parent.mapper.get_property(key) for value, attr_name in zip( self.__composite_values__(), prop._attribute_keys ): - setattr(parent, attr_name, value) + setattr(parent.obj(), attr_name, value) def _setup_composite_listener(): |
