diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-08-14 19:58:34 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-08-14 19:58:34 -0400 |
| commit | 59141d360e70d1a762719206e3cb0220b4c53fef (patch) | |
| tree | 954d39dfa15a5c7b3970549dd77ec96a72444876 /lib/sqlalchemy/orm/state.py | |
| parent | 688d799814fff2642926d3bce93b45965cf262da (diff) | |
| download | sqlalchemy-59141d360e70d1a762719206e3cb0220b4c53fef.tar.gz | |
- apply an import refactoring to the ORM as well
- rework the event system so that event modules load after their
targets, dependencies are reversed
- create an improved strategy lookup system for the ORM
- rework the ORM to have very few import cycles
- move out "importlater" to just util.dependency
- other tricks to cross-populate modules in as clear a way as possible
Diffstat (limited to 'lib/sqlalchemy/orm/state.py')
| -rw-r--r-- | lib/sqlalchemy/orm/state.py | 84 |
1 files changed, 32 insertions, 52 deletions
diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index c479d880d..7805a47e4 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -13,16 +13,11 @@ defines a large part of the ORM's interactivity. import weakref from .. import util -from . import exc as orm_exc, attributes, util as orm_util, interfaces -from .attributes import ( - PASSIVE_NO_RESULT, - SQL_OK, NEVER_SET, ATTR_WAS_SET, NO_VALUE,\ - PASSIVE_NO_INITIALIZE - ) -sessionlib = util.importlater("sqlalchemy.orm", "session") -instrumentation = util.importlater("sqlalchemy.orm", "instrumentation") -mapperlib = util.importlater("sqlalchemy.orm", "mapperlib") - +from . import exc as orm_exc, interfaces +from .path_registry import PathRegistry +from .base import PASSIVE_NO_RESULT, SQL_OK, NEVER_SET, ATTR_WAS_SET, \ + NO_VALUE, PASSIVE_NO_INITIALIZE +from . import base class InstanceState(interfaces._InspectionAttr): """tracks state information at the instance level.""" @@ -89,15 +84,16 @@ class InstanceState(interfaces._InspectionAttr): not self._attached @property - def _attached(self): + @util.dependencies("sqlalchemy.orm.session") + def _attached(self, sessionlib): return self.session_id is not None and \ self.session_id in sessionlib._sessions @property - def session(self): + @util.dependencies("sqlalchemy.orm.session") + def session(self, sessionlib): """Return the owning :class:`.Session` for this instance, or ``None`` if none available.""" - return sessionlib._state_session(self) @property @@ -186,7 +182,7 @@ class InstanceState(interfaces._InspectionAttr): def dict(self): o = self.obj() if o is not None: - return attributes.instance_dict(o) + return base.instance_dict(o) else: return {} @@ -214,8 +210,8 @@ class InstanceState(interfaces._InspectionAttr): return self._pending_mutations[key] def __getstate__(self): - d = {'instance': self.obj()} - d.update( + state_dict = {'instance': self.obj()} + state_dict.update( (k, self.__dict__[k]) for k in ( 'committed_state', '_pending_mutations', 'modified', 'expired', 'callables', 'key', 'parents', 'load_options', @@ -223,14 +219,14 @@ class InstanceState(interfaces._InspectionAttr): ) if k in self.__dict__ ) if self.load_path: - d['load_path'] = self.load_path.serialize() + state_dict['load_path'] = self.load_path.serialize() - self.manager.dispatch.pickle(self, d) + state_dict['manager'] = self.manager._serialize(self, state_dict) - return d + return state_dict - def __setstate__(self, state): - inst = state['instance'] + def __setstate__(self, state_dict): + inst = state_dict['instance'] if inst is not None: self.obj = weakref.ref(inst, self._cleanup) self.class_ = inst.__class__ @@ -239,42 +235,26 @@ class InstanceState(interfaces._InspectionAttr): # due to storage of state in "parents". "class_" # also new. self.obj = None - self.class_ = state['class_'] - self.manager = manager = instrumentation.manager_of_class(self.class_) - if manager is None: - raise orm_exc.UnmappedInstanceError( - inst, - "Cannot deserialize object of type %r - " - "no mapper() has " - "been configured for this class within the current " - "Python process!" % - self.class_) - elif manager.is_mapped and not manager.mapper.configured: - mapperlib.configure_mappers() - - self.committed_state = state.get('committed_state', {}) - self._pending_mutations = state.get('_pending_mutations', {}) - self.parents = state.get('parents', {}) - self.modified = state.get('modified', False) - self.expired = state.get('expired', False) - self.callables = state.get('callables', {}) + self.class_ = state_dict['class_'] + + self.committed_state = state_dict.get('committed_state', {}) + self._pending_mutations = state_dict.get('_pending_mutations', {}) + self.parents = state_dict.get('parents', {}) + self.modified = state_dict.get('modified', False) + self.expired = state_dict.get('expired', False) + self.callables = state_dict.get('callables', {}) self.__dict__.update([ - (k, state[k]) for k in ( + (k, state_dict[k]) for k in ( 'key', 'load_options', - ) if k in state + ) if k in state_dict ]) - if 'load_path' in state: - self.load_path = orm_util.PathRegistry.\ - deserialize(state['load_path']) + if 'load_path' in state_dict: + self.load_path = PathRegistry.\ + deserialize(state_dict['load_path']) - # setup _sa_instance_state ahead of time so that - # unpickle events can access the object normally. - # see [ticket:2362] - if inst is not None: - manager.setup_instance(inst, self) - manager.dispatch.unpickle(self, state) + state_dict['manager'](self, inst, state_dict) def _initialize(self, key): """Set this attribute to an empty value or collection, @@ -461,7 +441,7 @@ class InstanceState(interfaces._InspectionAttr): "collected." % ( self.manager[attr.key], - orm_util.state_class_str(self) + base.state_class_str(self) )) self.modified = True |
