diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-12-21 21:37:52 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-12-21 21:37:52 -0500 |
| commit | b79a5e7640fc1c8ca7acce5bfd2509ddf0102080 (patch) | |
| tree | 4fce95f955d2f1ca15ded2c3030e78b79e82cb68 /lib/sqlalchemy/orm | |
| parent | dff4e0591eee3def7c4c38666c8fc581c327aa87 (diff) | |
| download | sqlalchemy-b79a5e7640fc1c8ca7acce5bfd2509ddf0102080.tar.gz | |
- another heap of inlinings and now I really have to be done with this
Diffstat (limited to 'lib/sqlalchemy/orm')
| -rw-r--r-- | lib/sqlalchemy/orm/events.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/identity.py | 17 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/instrumentation.py | 16 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 20 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/query.py | 9 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/session.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/state.py | 28 |
7 files changed, 54 insertions, 47 deletions
diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py index 718a18606..6d1e8f713 100644 --- a/lib/sqlalchemy/orm/events.py +++ b/lib/sqlalchemy/orm/events.py @@ -96,6 +96,11 @@ class InstanceEvents(event.Events): @classmethod def remove(cls, identifier, target, fn): raise NotImplementedError("Removal of instance events not yet implemented") + + def on_first_init(self, manager, cls): + """Called when the first instance of a particular mapping is called. + + """ def on_init(self, target, args, kwargs): """Receive an instance when it's constructor is called. diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py index f1400a8c6..c55db39dc 100644 --- a/lib/sqlalchemy/orm/identity.py +++ b/lib/sqlalchemy/orm/identity.py @@ -151,7 +151,9 @@ class WeakInstanceDict(IdentityMap): self._remove_mutex.acquire() try: if dict.pop(self, state.key) is not state: - raise AssertionError("State %s is not present in this identity map" % state) + raise AssertionError( + "State %s is not present in this " + "identity map" % state) finally: self._remove_mutex.release() @@ -245,15 +247,20 @@ class StrongInstanceDict(IdentityMap): def add(self, state): if state.key in self: - if attributes.instance_state(dict.__getitem__(self, state.key)) is not state: - raise AssertionError("A conflicting state is already present in the identity map for key %r" % (state.key, )) + if attributes.instance_state(dict.__getitem__(self, + state.key)) is not state: + raise AssertionError('A conflicting state is already ' + 'present in the identity map for key %r' + % (state.key, )) else: dict.__setitem__(self, state.key, state.obj()) self._manage_incoming_state(state) def remove(self, state): - if attributes.instance_state(dict.pop(self, state.key)) is not state: - raise AssertionError("State %s is not present in this identity map" % state) + if attributes.instance_state(dict.pop(self, state.key)) \ + is not state: + raise AssertionError('State %s is not present in this ' + 'identity map' % state) self._manage_removed_state(state) def discard(self, state): diff --git a/lib/sqlalchemy/orm/instrumentation.py b/lib/sqlalchemy/orm/instrumentation.py index dba3a6830..9876dde3f 100644 --- a/lib/sqlalchemy/orm/instrumentation.py +++ b/lib/sqlalchemy/orm/instrumentation.py @@ -166,11 +166,13 @@ class ClassManager(dict): self.uninstall_member('__init__') self.new_init = None - def _create_instance_state(self, instance): + @util.memoized_property + def _state_constructor(self): + self.dispatch.on_first_init(self, self.class_) if self.mutable_attributes: - return state.MutableAttrInstanceState(instance, self) + return state.MutableAttrInstanceState else: - return state.InstanceState(instance, self) + return state.InstanceState def manage(self): """Mark this instance as the manager for its class.""" @@ -290,12 +292,12 @@ class ClassManager(dict): def new_instance(self, state=None): instance = self.class_.__new__(self.class_) setattr(instance, self.STATE_ATTR, - state or self._create_instance_state(instance)) + state or self._state_constructor(instance, self)) return instance def setup_instance(self, instance, state=None): setattr(instance, self.STATE_ATTR, - state or self._create_instance_state(instance)) + state or self._state_constructor(instance, self)) def teardown_instance(self, instance): delattr(instance, self.STATE_ATTR) @@ -318,7 +320,7 @@ class ClassManager(dict): return self._subclass_manager(instance.__class__).\ _new_state_if_none(instance) else: - state = self._create_instance_state(instance) + state = self._state_constructor(instance, self) setattr(instance, self.STATE_ATTR, state) return state @@ -421,7 +423,7 @@ class _ClassInstrumentationAdapter(ClassManager): self._adapted.initialize_instance_dict(self.class_, instance) if state is None: - state = self._create_instance_state(instance) + state = self._state_constructor(instance, self) # the given instance is assumed to have no state self._adapted.install_state(self.class_, instance, state) diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 9bb84e86c..91d512ad0 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -400,6 +400,7 @@ class Mapper(object): if manager.info.get(_INSTRUMENTOR, False): return + event.listen(manager, 'on_first_init', _event_on_first_init, raw=True) event.listen(manager, 'on_init', _event_on_init, raw=True) event.listen(manager, 'on_resurrect', _event_on_resurrect, raw=True) @@ -2455,17 +2456,22 @@ def _event_on_load(state): instrumenting_mapper = state.manager.info[_INSTRUMENTOR] if instrumenting_mapper._reconstructor: instrumenting_mapper._reconstructor(state.obj()) - -def _event_on_init(state, args, kwargs): - """Trigger mapper compilation and run init_instance hooks.""" - instrumenting_mapper = state.manager.info.get(_INSTRUMENTOR) +def _event_on_first_init(manager, cls): + """Trigger mapper compilation.""" + + instrumenting_mapper = manager.info.get(_INSTRUMENTOR) if instrumenting_mapper: if _new_mappers: configure_mappers() - - if instrumenting_mapper._set_polymorphic_identity: - instrumenting_mapper._set_polymorphic_identity(state) + +def _event_on_init(state, args, kwargs): + """Run init_instance hooks.""" + + instrumenting_mapper = state.manager.info.get(_INSTRUMENTOR) + if instrumenting_mapper and \ + instrumenting_mapper._set_polymorphic_identity: + instrumenting_mapper._set_polymorphic_identity(state) def _event_on_resurrect(state): # re-populate the primary key elements diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 9c0381f75..74678a8d2 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1721,9 +1721,10 @@ class Query(object): return self._execute_and_instances(context) def _execute_and_instances(self, querycontext): - result = self.session.execute( - querycontext.statement, params=self._params, - mapper=self._mapper_zero_or_none()) + result = self.session.connection( + mapper = self._mapper_zero_or_none(), + clause = querycontext.statement, + close_with_result=True).execute(querycontext.statement, self._params) return self.instances(result, querycontext) @property @@ -1795,7 +1796,7 @@ class Query(object): if filtered: if single_entity: - filter = lambda x: util.unique_list(x, util.IdentitySet) + filter = lambda x: util.unique_list(x, id) else: filter = util.unique_list else: diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 325a94643..eba4ace8c 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -635,7 +635,8 @@ class Session(object): self.transaction.prepare() - def connection(self, mapper=None, clause=None): + def connection(self, mapper=None, clause=None, + close_with_result=False, **kw): """Return the active Connection. Retrieves the ``Connection`` managing the current transaction. Any @@ -657,7 +658,8 @@ class Session(object): Optional, any ``ClauseElement`` """ - return self._connection_for_bind(self.get_bind(mapper, clause)) + return self._connection_for_bind(self.get_bind(mapper, clause, **kw), + close_with_result=close_with_result) def _connection_for_bind(self, engine, **kwargs): if self.transaction is not None: diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 909977cc4..52cde3a30 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -52,11 +52,7 @@ class InstanceState(object): return bool(self.key) def detach(self): - if self.session_id: - try: - del self.session_id - except AttributeError: - pass + self.session_id = None def dispose(self): self.detach() @@ -70,15 +66,8 @@ class InstanceState(object): except AssertionError: pass - # remove possible cycles - self.callables.clear() - - # inlining of self.dispose() - if self.session_id: - try: - del self.session_id - except AttributeError: - pass + self.callables = {} + self.session_id = None del self.obj def obj(self): @@ -102,14 +91,9 @@ class InstanceState(object): manager.dispatch.on_init(self, args, kwargs) - # LESSTHANIDEAL: - # adjust for the case where the InstanceState was created before - # mapper compilation, and this actually needs to be a MutableAttrInstanceState - if manager.mutable_attributes and self.__class__ is not MutableAttrInstanceState: - self.__class__ = MutableAttrInstanceState - self.obj = weakref.ref(self.obj(), self._cleanup) - self.mutable_dict = {} - + #if manager.mutable_attributes: + # assert self.__class__ is MutableAttrInstanceState + try: return manager.original_init(*mixed[1:], **kwargs) except: |
