summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/events.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/events.py')
-rw-r--r--lib/sqlalchemy/orm/events.py127
1 files changed, 71 insertions, 56 deletions
diff --git a/lib/sqlalchemy/orm/events.py b/lib/sqlalchemy/orm/events.py
index 0e08a0898..aa99673ba 100644
--- a/lib/sqlalchemy/orm/events.py
+++ b/lib/sqlalchemy/orm/events.py
@@ -18,6 +18,7 @@ from .session import Session, sessionmaker
from .scoping import scoped_session
from .attributes import QueryableAttribute
+
class InstrumentationEvents(event.Events):
"""Events related to class instrumentation events.
@@ -50,7 +51,6 @@ class InstrumentationEvents(event.Events):
_target_class_doc = "SomeBaseClass"
_dispatch_target = instrumentation.InstrumentationFactory
-
@classmethod
def _accept_with(cls, target):
if isinstance(target, type):
@@ -71,10 +71,11 @@ class InstrumentationEvents(event.Events):
return fn(target_cls, *arg)
def remove(ref):
- key = event.registry._EventKey(None, identifier, listen,
- instrumentation._instrumentation_factory)
+ key = event.registry._EventKey(
+ None, identifier, listen,
+ instrumentation._instrumentation_factory)
getattr(instrumentation._instrumentation_factory.dispatch,
- identifier).remove(key)
+ identifier).remove(key)
target = weakref.ref(target.class_, remove)
@@ -107,17 +108,18 @@ class InstrumentationEvents(event.Events):
"""Called when an attribute is instrumented."""
-
class _InstrumentationEventsHold(object):
"""temporary marker object used to transfer from _accept_with() to
_listen() on the InstrumentationEvents class.
"""
+
def __init__(self, class_):
self.class_ = class_
dispatch = event.dispatcher(InstrumentationEvents)
+
class InstanceEvents(event.Events):
"""Define events specific to object lifecycle.
@@ -201,7 +203,8 @@ class InstanceEvents(event.Events):
if propagate:
for mgr in target.subclass_managers(True):
- event_key.with_dispatch_target(mgr).base_listen(propagate=True)
+ event_key.with_dispatch_target(mgr).base_listen(
+ propagate=True)
@classmethod
def _clear(cls):
@@ -330,6 +333,7 @@ class InstanceEvents(event.Events):
"""
+
class _EventsHold(event.RefCollection):
"""Hold onto listeners against unmapped, uninstrumented classes.
@@ -337,6 +341,7 @@ class _EventsHold(event.RefCollection):
those objects are created for that class.
"""
+
def __init__(self, class_):
self.class_ = class_
@@ -387,9 +392,9 @@ class _EventsHold(event.RefCollection):
collection = cls.all_holds[subclass]
for event_key, raw, propagate in collection.values():
if propagate or subclass is class_:
- # since we can't be sure in what order different classes
- # in a hierarchy are triggered with populate(),
- # we rely upon _EventsHold for all event
+ # since we can't be sure in what order different
+ # classes in a hierarchy are triggered with
+ # populate(), we rely upon _EventsHold for all event
# assignment, instead of using the generic propagate
# flag.
event_key.with_dispatch_target(subject).\
@@ -502,16 +507,17 @@ class MapperEvents(event.Events):
return target
@classmethod
- def _listen(cls, event_key, raw=False, retval=False, propagate=False, **kw):
+ def _listen(
+ cls, event_key, raw=False, retval=False, propagate=False, **kw):
target, identifier, fn = \
event_key.dispatch_target, event_key.identifier, event_key.fn
if identifier in ("before_configured", "after_configured") and \
- target is not mapperlib.Mapper:
+ target is not mapperlib.Mapper:
util.warn(
- "'before_configured' and 'after_configured' ORM events "
- "only invoke with the mapper() function or Mapper class "
- "as the target.")
+ "'before_configured' and 'after_configured' ORM events "
+ "only invoke with the mapper() function or Mapper class "
+ "as the target.")
if not raw or not retval:
if not raw:
@@ -536,7 +542,7 @@ class MapperEvents(event.Events):
if propagate:
for mapper in target.self_and_descendants:
event_key.with_dispatch_target(mapper).base_listen(
- propagate=True, **kw)
+ propagate=True, **kw)
else:
event_key.base_listen(**kw)
@@ -722,7 +728,7 @@ class MapperEvents(event.Events):
"""
def append_result(self, mapper, context, row, target,
- result, **flags):
+ result, **flags):
"""Receive an object instance before that instance is appended
to a result list.
@@ -759,7 +765,7 @@ class MapperEvents(event.Events):
"""
def populate_instance(self, mapper, context, row,
- target, **flags):
+ target, **flags):
"""Receive an instance before that instance has
its attributes populated.
@@ -1165,6 +1171,7 @@ class MapperEvents(event.Events):
"""
+
class _MapperEventsHold(_EventsHold):
all_holds = weakref.WeakKeyDictionary()
@@ -1215,11 +1222,11 @@ class SessionEvents(event.Events):
(
not isinstance(target, type) or
not issubclass(target, Session)
- ):
+ ):
raise exc.ArgumentError(
- "Session event listen on a scoped_session "
- "requires that its creation callable "
- "is associated with the Session class.")
+ "Session event listen on a scoped_session "
+ "requires that its creation callable "
+ "is associated with the Session class.")
if isinstance(target, sessionmaker):
return target.class_
@@ -1284,8 +1291,10 @@ class SessionEvents(event.Events):
The :meth:`~.SessionEvents.before_commit` hook is *not* per-flush,
that is, the :class:`.Session` can emit SQL to the database
many times within the scope of a transaction.
- For interception of these events, use the :meth:`~.SessionEvents.before_flush`,
- :meth:`~.SessionEvents.after_flush`, or :meth:`~.SessionEvents.after_flush_postexec`
+ For interception of these events, use the
+ :meth:`~.SessionEvents.before_flush`,
+ :meth:`~.SessionEvents.after_flush`, or
+ :meth:`~.SessionEvents.after_flush_postexec`
events.
:param session: The target :class:`.Session`.
@@ -1310,16 +1319,19 @@ class SessionEvents(event.Events):
The :meth:`~.SessionEvents.after_commit` hook is *not* per-flush,
that is, the :class:`.Session` can emit SQL to the database
many times within the scope of a transaction.
- For interception of these events, use the :meth:`~.SessionEvents.before_flush`,
- :meth:`~.SessionEvents.after_flush`, or :meth:`~.SessionEvents.after_flush_postexec`
+ For interception of these events, use the
+ :meth:`~.SessionEvents.before_flush`,
+ :meth:`~.SessionEvents.after_flush`, or
+ :meth:`~.SessionEvents.after_flush_postexec`
events.
.. note::
The :class:`.Session` is not in an active transaction
- when the :meth:`~.SessionEvents.after_commit` event is invoked, and therefore
- can not emit SQL. To emit SQL corresponding to every transaction,
- use the :meth:`~.SessionEvents.before_commit` event.
+ when the :meth:`~.SessionEvents.after_commit` event is invoked,
+ and therefore can not emit SQL. To emit SQL corresponding to
+ every transaction, use the :meth:`~.SessionEvents.before_commit`
+ event.
:param session: The target :class:`.Session`.
@@ -1467,8 +1479,8 @@ class SessionEvents(event.Events):
This is called before an add, delete or merge causes
the object to be part of the session.
- .. versionadded:: 0.8. Note that :meth:`~.SessionEvents.after_attach` now
- fires off after the item is part of the session.
+ .. versionadded:: 0.8. Note that :meth:`~.SessionEvents.after_attach`
+ now fires off after the item is part of the session.
:meth:`.before_attach` is provided for those cases where
the item should not yet be part of the session state.
@@ -1501,12 +1513,12 @@ class SessionEvents(event.Events):
"""
@event._legacy_signature("0.9",
- ["session", "query", "query_context", "result"],
- lambda update_context: (
- update_context.session,
- update_context.query,
- update_context.context,
- update_context.result))
+ ["session", "query", "query_context", "result"],
+ lambda update_context: (
+ update_context.session,
+ update_context.query,
+ update_context.context,
+ update_context.result))
def after_bulk_update(self, update_context):
"""Execute after a bulk update operation to the session.
@@ -1516,8 +1528,8 @@ class SessionEvents(event.Events):
details about the update, including these attributes:
* ``session`` - the :class:`.Session` involved
- * ``query`` -the :class:`.Query` object that this update operation was
- called upon.
+ * ``query`` -the :class:`.Query` object that this update operation
+ was called upon.
* ``context`` The :class:`.QueryContext` object, corresponding
to the invocation of an ORM query.
* ``result`` the :class:`.ResultProxy` returned as a result of the
@@ -1527,12 +1539,12 @@ class SessionEvents(event.Events):
"""
@event._legacy_signature("0.9",
- ["session", "query", "query_context", "result"],
- lambda delete_context: (
- delete_context.session,
- delete_context.query,
- delete_context.context,
- delete_context.result))
+ ["session", "query", "query_context", "result"],
+ lambda delete_context: (
+ delete_context.session,
+ delete_context.query,
+ delete_context.context,
+ delete_context.result))
def after_bulk_delete(self, delete_context):
"""Execute after a bulk delete operation to the session.
@@ -1542,8 +1554,8 @@ class SessionEvents(event.Events):
details about the update, including these attributes:
* ``session`` - the :class:`.Session` involved
- * ``query`` -the :class:`.Query` object that this update operation was
- called upon.
+ * ``query`` -the :class:`.Query` object that this update operation
+ was called upon.
* ``context`` The :class:`.QueryContext` object, corresponding
to the invocation of an ORM query.
* ``result`` the :class:`.ResultProxy` returned as a result of the
@@ -1628,8 +1640,8 @@ class AttributeEvents(event.Events):
@classmethod
def _listen(cls, event_key, active_history=False,
- raw=False, retval=False,
- propagate=False):
+ raw=False, retval=False,
+ propagate=False):
target, identifier, fn = \
event_key.dispatch_target, event_key.identifier, event_key.fn
@@ -1654,7 +1666,8 @@ class AttributeEvents(event.Events):
manager = instrumentation.manager_of_class(target.class_)
for mgr in manager.subclass_managers(True):
- event_key.with_dispatch_target(mgr[target.key]).base_listen(propagate=True)
+ event_key.with_dispatch_target(
+ mgr[target.key]).base_listen(propagate=True)
def append(self, target, value, initiator):
"""Receive a collection append event.
@@ -1672,8 +1685,9 @@ class AttributeEvents(event.Events):
chained event propagation.
.. versionchanged:: 0.9.0 the ``initiator`` argument is now
- passed as a :class:`.attributes.Event` object, and may be modified
- by backref handlers within a chain of backref-linked events.
+ passed as a :class:`.attributes.Event` object, and may be
+ modified by backref handlers within a chain of backref-linked
+ events.
:return: if the event was registered with ``retval=True``,
the given value, or a new effective value, should be returned.
@@ -1693,8 +1707,9 @@ class AttributeEvents(event.Events):
chained event propagation.
.. versionchanged:: 0.9.0 the ``initiator`` argument is now
- passed as a :class:`.attributes.Event` object, and may be modified
- by backref handlers within a chain of backref-linked events.
+ passed as a :class:`.attributes.Event` object, and may be
+ modified by backref handlers within a chain of backref-linked
+ events.
:return: No return value is defined for this event.
"""
@@ -1721,11 +1736,11 @@ class AttributeEvents(event.Events):
chained event propagation.
.. versionchanged:: 0.9.0 the ``initiator`` argument is now
- passed as a :class:`.attributes.Event` object, and may be modified
- by backref handlers within a chain of backref-linked events.
+ passed as a :class:`.attributes.Event` object, and may be
+ modified by backref handlers within a chain of backref-linked
+ events.
:return: if the event was registered with ``retval=True``,
the given value, or a new effective value, should be returned.
"""
-