summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-12-21 21:37:52 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2010-12-21 21:37:52 -0500
commitb79a5e7640fc1c8ca7acce5bfd2509ddf0102080 (patch)
tree4fce95f955d2f1ca15ded2c3030e78b79e82cb68 /lib/sqlalchemy/orm
parentdff4e0591eee3def7c4c38666c8fc581c327aa87 (diff)
downloadsqlalchemy-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.py5
-rw-r--r--lib/sqlalchemy/orm/identity.py17
-rw-r--r--lib/sqlalchemy/orm/instrumentation.py16
-rw-r--r--lib/sqlalchemy/orm/mapper.py20
-rw-r--r--lib/sqlalchemy/orm/query.py9
-rw-r--r--lib/sqlalchemy/orm/session.py6
-rw-r--r--lib/sqlalchemy/orm/state.py28
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: