diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-04-23 18:59:17 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-04-23 18:59:17 -0400 |
commit | 841ea194bd7cf239323ee21320210fd6dc5c551d (patch) | |
tree | 0da6b6ae37d5def93b84e06afd451f50716c6caf /lib/sqlalchemy/orm/state.py | |
parent | 101da94e1282a410557784272bda58222ac048b4 (diff) | |
download | sqlalchemy-841ea194bd7cf239323ee21320210fd6dc5c551d.tar.gz |
- [removed] The legacy "mutable" system of the
ORM, including the MutableType class as well
as the mutable=True flag on PickleType
and postgresql.ARRAY has been removed.
In-place mutations are detected by the ORM
using the sqlalchemy.ext.mutable extension,
introduced in 0.7. The removal of MutableType
and associated constructs removes a great
deal of complexity from SQLAlchemy's internals.
The approach performed poorly as it would incur
a scan of the full contents of the Session
when in use. [ticket:2442]
Diffstat (limited to 'lib/sqlalchemy/orm/state.py')
-rw-r--r-- | lib/sqlalchemy/orm/state.py | 135 |
1 files changed, 4 insertions, 131 deletions
diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 64fca8715..bb6104762 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -33,7 +33,6 @@ class InstanceState(object): load_options = EMPTY_SET load_path = () insert_order = None - mutable_dict = None _strong_obj = None modified = False expired = False @@ -150,9 +149,6 @@ class InstanceState(object): manager.dispatch.init(self, args, kwargs) - #if manager.mutable_attributes: - # assert self.__class__ is MutableAttrInstanceState - try: return manager.original_init(*mixed[1:], **kwargs) except: @@ -175,7 +171,7 @@ class InstanceState(object): d.update( (k, self.__dict__[k]) for k in ( 'committed_state', '_pending_mutations', 'modified', 'expired', - 'callables', 'key', 'parents', 'load_options', 'mutable_dict', + 'callables', 'key', 'parents', 'load_options', 'class_', ) if k in self.__dict__ ) @@ -220,7 +216,7 @@ class InstanceState(object): self.__dict__.update([ (k, state[k]) for k in ( - 'key', 'load_options', 'mutable_dict' + 'key', 'load_options', ) if k in state ]) @@ -275,7 +271,6 @@ class InstanceState(object): self.committed_state.clear() self.__dict__.pop('_pending_mutations', None) - self.__dict__.pop('mutable_dict', None) # clear out 'parents' collection. not # entirely clear how we can best determine @@ -293,7 +288,6 @@ class InstanceState(object): def expire_attributes(self, dict_, attribute_names): pending = self.__dict__.get('_pending_mutations', None) - mutable_dict = self.mutable_dict for key in attribute_names: impl = self.manager[key].impl @@ -302,8 +296,6 @@ class InstanceState(object): dict_.pop(key, None) self.committed_state.pop(key, None) - if mutable_dict: - mutable_dict.pop(key, None) if pending: pending.pop(key, None) @@ -421,15 +413,8 @@ class InstanceState(object): """ class_manager = self.manager - if class_manager.mutable_attributes: - for key in keys: - if key in dict_ and key in class_manager.mutable_attributes: - self.committed_state[key] = self.manager[key].impl.copy(dict_[key]) - else: - self.committed_state.pop(key, None) - else: - for key in keys: - self.committed_state.pop(key, None) + for key in keys: + self.committed_state.pop(key, None) self.expired = False @@ -462,10 +447,6 @@ class InstanceState(object): if key in dict_ and callables[key] is self: del callables[key] - for key in self.manager.mutable_attributes: - if key in dict_: - self.committed_state[key] = self.manager[key].impl.copy(dict_[key]) - if instance_dict and self.modified: instance_dict._modified.discard(self) @@ -493,114 +474,6 @@ class InspectAttr(object): return self.state.get_history(self.key, PASSIVE_NO_INITIALIZE) -class MutableAttrInstanceState(InstanceState): - """InstanceState implementation for objects that reference 'mutable' - attributes. - - Has a more involved "cleanup" handler that checks mutable attributes - for changes upon dereference, resurrecting if needed. - - """ - - @util.memoized_property - def mutable_dict(self): - return {} - - def _get_modified(self, dict_=None): - if self.__dict__.get('modified', False): - return True - else: - if dict_ is None: - dict_ = self.dict - for key in self.manager.mutable_attributes: - if self.manager[key].impl.check_mutable_modified(self, dict_): - return True - else: - return False - - def _set_modified(self, value): - self.__dict__['modified'] = value - - modified = property(_get_modified, _set_modified) - - @property - def unmodified(self): - """a set of keys which have no uncommitted changes""" - - dict_ = self.dict - - return set([ - key for key in self.manager - if (key not in self.committed_state or - (key in self.manager.mutable_attributes and - not self.manager[key].impl.check_mutable_modified(self, dict_)))]) - - def unmodified_intersection(self, keys): - """Return self.unmodified.intersection(keys).""" - - dict_ = self.dict - - return set([ - key for key in keys - if (key not in self.committed_state or - (key in self.manager.mutable_attributes and - not self.manager[key].impl.check_mutable_modified(self, dict_)))]) - - - def _is_really_none(self): - """do a check modified/resurrect. - - This would be called in the extremely rare - race condition that the weakref returned None but - the cleanup handler had not yet established the - __resurrect callable as its replacement. - - """ - if self.modified: - self.obj = self.__resurrect - return self.obj() - else: - return None - - def reset(self, dict_, key): - self.mutable_dict.pop(key, None) - InstanceState.reset(self, dict_, key) - - def _cleanup(self, ref): - """weakref callback. - - This method may be called by an asynchronous - gc. - - If the state shows pending changes, the weakref - is replaced by the __resurrect callable which will - re-establish an object reference on next access, - else removes this InstanceState from the owning - identity map, if any. - - """ - if self._get_modified(self.mutable_dict): - self.obj = self.__resurrect - else: - instance_dict = self._instance_dict() - if instance_dict: - instance_dict.discard(self) - self._dispose() - - def __resurrect(self): - """A substitute for the obj() weakref function which resurrects.""" - - # store strong ref'ed version of the object; will revert - # to weakref when changes are persisted - obj = self.manager.new_instance(state=self) - self.obj = weakref.ref(obj, self._cleanup) - self._strong_obj = obj - obj.__dict__.update(self.mutable_dict) - - # re-establishes identity attributes from the key - self.manager.dispatch.resurrect(self) - - return obj class PendingCollection(object): """A writable placeholder for an unloaded collection. |