summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/state.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-04-23 18:59:17 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-04-23 18:59:17 -0400
commit841ea194bd7cf239323ee21320210fd6dc5c551d (patch)
tree0da6b6ae37d5def93b84e06afd451f50716c6caf /lib/sqlalchemy/orm/state.py
parent101da94e1282a410557784272bda58222ac048b4 (diff)
downloadsqlalchemy-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.py135
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.