mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-11 03:10:38 -04:00
- event documentation bonanza
This commit is contained in:
Vendored
+21
-4
@@ -8,8 +8,6 @@ the internals of both SQLAlchemy Core and ORM. The system is all new
|
||||
as of version 0.7 and supercedes the previous system of "extension", "proxy",
|
||||
and "listener" classes.
|
||||
|
||||
Core events are described in :ref:`core_event_toplevel` and ORM events in :ref:`orm_event_toplevel`.
|
||||
|
||||
Event Registration
|
||||
------------------
|
||||
|
||||
@@ -21,7 +19,7 @@ instructions regarding secondary event targets based on the given target.
|
||||
|
||||
The name of an event and the argument signature of a corresponding listener function is derived from
|
||||
a class bound specification method, which exists bound to a marker class that's described in the documentation.
|
||||
For example, the documentation for :ref:`.PoolEvents.on_connect` indicates that the event name is ``"on_connect"``
|
||||
For example, the documentation for :meth:`.PoolEvents.on_connect` indicates that the event name is ``"on_connect"``
|
||||
and that a user-defined listener function should receive two positional arguments::
|
||||
|
||||
from sqlalchemy.event import listen
|
||||
@@ -82,6 +80,25 @@ which modifies the subsequent handling. By default, no listener ever requires
|
||||
# it to use the return value
|
||||
listen(validate_phone, 'on_set', UserContact.phone, retval=True)
|
||||
|
||||
|
||||
Event Reference
|
||||
----------------
|
||||
|
||||
Both SQLAlchemy Core and SQLAlchemy ORM feature a wide variety of event hooks:
|
||||
|
||||
* **Core Events** - these are described in
|
||||
:ref:`core_event_toplevel` and include event hooks specific to
|
||||
connection pool lifecycle, SQL statement execution,
|
||||
transaction lifecycle, and schema creation and teardown.
|
||||
|
||||
* **ORM Events** - these are described in
|
||||
:ref:`orm_event_toplevel`, and include event hooks specific to
|
||||
class and attribute instrumentation, object initialization
|
||||
hooks, attribute on-change hooks, session state, flush, and
|
||||
commit hooks, mapper initialization, object/result population,
|
||||
and per-instance persistence hooks.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. autofunction:: sqlalchemy.event.listen
|
||||
|
||||
|
||||
Vendored
+6
-2
@@ -3,8 +3,12 @@
|
||||
Core Events
|
||||
============
|
||||
|
||||
This section describes the event interfaces provided in SQLAlchemy Core. For an introduction
|
||||
to the event listening API, see :ref:`event_toplevel`. ORM events are described in :ref:`orm_event_toplevel`.
|
||||
This section describes the event interfaces provided in
|
||||
SQLAlchemy Core. The event system in 0.7 is all new and
|
||||
supercedes the previous system of "extension", "listener", and
|
||||
"proxy" classes. For an introduction to the event listening API,
|
||||
see :ref:`event_toplevel`. ORM events are described in
|
||||
:ref:`orm_event_toplevel`.
|
||||
|
||||
Connection Pool Events
|
||||
-----------------------
|
||||
|
||||
Vendored
+17
-7
@@ -5,7 +5,9 @@ ORM Events
|
||||
|
||||
The ORM includes a wide variety of hooks available for subscription. The event
|
||||
system in 0.7 is all new and supercedes the previous system of "extension" classes.
|
||||
For an introduction to the event API, see :ref:`core_event_toplevel`.
|
||||
For an introduction to the event API, see :ref:`event_toplevel`. Non-ORM events
|
||||
such as those regarding connections and low-level statement execution are described in
|
||||
:ref:`core_event_toplevel`.
|
||||
|
||||
Attribute Events
|
||||
----------------
|
||||
@@ -13,12 +15,6 @@ Attribute Events
|
||||
.. autoclass:: sqlalchemy.orm.events.AttributeEvents
|
||||
:members:
|
||||
|
||||
Instrumentation Events
|
||||
-----------------------
|
||||
|
||||
.. autoclass:: sqlalchemy.orm.events.InstrumentationEvents
|
||||
:members:
|
||||
|
||||
Mapper Events
|
||||
---------------
|
||||
|
||||
@@ -36,3 +32,17 @@ Session Events
|
||||
|
||||
TODO
|
||||
|
||||
Instrumentation Events
|
||||
-----------------------
|
||||
|
||||
.. autoclass:: sqlalchemy.orm.events.InstrumentationEvents
|
||||
:members:
|
||||
|
||||
Alternate Class Instrumentation
|
||||
-------------------------------
|
||||
|
||||
.. autoclass:: sqlalchemy.orm.interfaces.InstrumentationManager
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
|
||||
Vendored
-73
@@ -16,91 +16,18 @@ a consistent interface to all events without the need for subclassing.
|
||||
Mapper Events
|
||||
-----------------
|
||||
|
||||
To use :class:`.MapperExtension`, make your own subclass of it and just send it off to a mapper::
|
||||
|
||||
from sqlalchemy.orm.interfaces import MapperExtension
|
||||
|
||||
class MyExtension(MapperExtension):
|
||||
def before_insert(self, mapper, connection, instance):
|
||||
print "instance %s before insert !" % instance
|
||||
|
||||
m = mapper(User, users_table, extension=MyExtension())
|
||||
|
||||
Multiple extensions will be chained together and processed in order; they are specified as a list::
|
||||
|
||||
m = mapper(User, users_table, extension=[ext1, ext2, ext3])
|
||||
|
||||
.. autoclass:: MapperExtension
|
||||
:members:
|
||||
|
||||
Session Events
|
||||
-----------------
|
||||
|
||||
The :class:`.SessionExtension` applies plugin points for :class:`.Session` objects::
|
||||
|
||||
from sqlalchemy.orm.interfaces import SessionExtension
|
||||
|
||||
class MySessionExtension(SessionExtension):
|
||||
def before_commit(self, session):
|
||||
print "before commit!"
|
||||
|
||||
Session = sessionmaker(extension=MySessionExtension())
|
||||
|
||||
The same :class:`~sqlalchemy.orm.interfaces.SessionExtension` instance can be
|
||||
used with any number of sessions.
|
||||
|
||||
.. autoclass:: SessionExtension
|
||||
:members:
|
||||
|
||||
Attribute Events
|
||||
--------------------
|
||||
|
||||
:class:`.AttributeExtension` is used to listen for set, remove, and append
|
||||
events on individual mapped attributes. It is established on an individual
|
||||
mapped attribute using the `extension` argument, available on
|
||||
:func:`.column_property`, :func:`.relationship`, and others::
|
||||
|
||||
from sqlalchemy.orm.interfaces import AttributeExtension
|
||||
from sqlalchemy.orm import mapper, relationship, column_property
|
||||
|
||||
class MyAttrExt(AttributeExtension):
|
||||
def append(self, state, value, initiator):
|
||||
print "append event !"
|
||||
return value
|
||||
|
||||
def set(self, state, value, oldvalue, initiator):
|
||||
print "set event !"
|
||||
return value
|
||||
|
||||
mapper(SomeClass, sometable, properties={
|
||||
'foo':column_property(sometable.c.foo, extension=MyAttrExt()),
|
||||
'bar':relationship(Bar, extension=MyAttrExt())
|
||||
})
|
||||
|
||||
Note that the :class:`AttributeExtension` methods
|
||||
:meth:`~.AttributeExtension.append` and :meth:`~.AttributeExtension.set` need
|
||||
to return the ``value`` parameter. The returned value is used as the effective
|
||||
value, and allows the extension to change what is ultimately persisted.
|
||||
|
||||
.. autoclass:: AttributeExtension
|
||||
:members:
|
||||
|
||||
Instrumentation Events and Re-implementation
|
||||
---------------------------------------------
|
||||
|
||||
:class:`.InstrumentationManager` can be subclassed in order to receive class
|
||||
instrumentation events as well as to change how class instrumentation
|
||||
proceeds. This class exists for the purposes of integration with other object
|
||||
management frameworks which would like to entirely modify the instrumentation
|
||||
methodology of the ORM, and is not intended for regular usage. One possible
|
||||
exception is the :meth:`.InstrumentationManager.post_configure_attribute`
|
||||
method, which can be useful for adding extensions to all mapped attributes,
|
||||
though a much better way to do this will be available in a future release of
|
||||
SQLAlchemy.
|
||||
|
||||
For an example of :class:`.InstrumentationManager`, see the example
|
||||
:ref:`examples_instrumentation`.
|
||||
|
||||
.. autoclass:: InstrumentationManager
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -52,16 +52,64 @@ class DDLEvents(event.Events):
|
||||
"""
|
||||
|
||||
def on_before_create(self, target, connection, **kw):
|
||||
""" """
|
||||
"""Called before CREATE statments are emitted.
|
||||
|
||||
:param target: the :class:`.MetaData` or :class:`.Table`
|
||||
object which is the target of the event.
|
||||
:param connection: the :class:`.Connection` where the
|
||||
CREATE statement or statements will be emitted.
|
||||
:param \**kw: additional keyword arguments relevant
|
||||
to the event. Currently this includes the ``tables``
|
||||
argument in the case of a :class:`.MetaData` object,
|
||||
which is the list of :class:`.Table` objects for which
|
||||
CREATE will be emitted.
|
||||
|
||||
"""
|
||||
|
||||
def on_after_create(self, target, connection, **kw):
|
||||
""" """
|
||||
"""Called after CREATE statments are emitted.
|
||||
|
||||
:param target: the :class:`.MetaData` or :class:`.Table`
|
||||
object which is the target of the event.
|
||||
:param connection: the :class:`.Connection` where the
|
||||
CREATE statement or statements have been emitted.
|
||||
:param \**kw: additional keyword arguments relevant
|
||||
to the event. Currently this includes the ``tables``
|
||||
argument in the case of a :class:`.MetaData` object,
|
||||
which is the list of :class:`.Table` objects for which
|
||||
CREATE has been emitted.
|
||||
|
||||
"""
|
||||
|
||||
def on_before_drop(self, target, connection, **kw):
|
||||
""" """
|
||||
"""Called before DROP statments are emitted.
|
||||
|
||||
:param target: the :class:`.MetaData` or :class:`.Table`
|
||||
object which is the target of the event.
|
||||
:param connection: the :class:`.Connection` where the
|
||||
DROP statement or statements will be emitted.
|
||||
:param \**kw: additional keyword arguments relevant
|
||||
to the event. Currently this includes the ``tables``
|
||||
argument in the case of a :class:`.MetaData` object,
|
||||
which is the list of :class:`.Table` objects for which
|
||||
DROP will be emitted.
|
||||
|
||||
"""
|
||||
|
||||
def on_after_drop(self, target, connection, **kw):
|
||||
""" """
|
||||
"""Called after DROP statments are emitted.
|
||||
|
||||
:param target: the :class:`.MetaData` or :class:`.Table`
|
||||
object which is the target of the event.
|
||||
:param connection: the :class:`.Connection` where the
|
||||
DROP statement or statements have been emitted.
|
||||
:param \**kw: additional keyword arguments relevant
|
||||
to the event. Currently this includes the ``tables``
|
||||
argument in the case of a :class:`.MetaData` object,
|
||||
which is the list of :class:`.Table` objects for which
|
||||
DROP has been emitted.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class PoolEvents(event.Events):
|
||||
|
||||
@@ -3,15 +3,31 @@ from interfaces import EXT_CONTINUE
|
||||
|
||||
|
||||
class MapperExtension(object):
|
||||
"""Base implementation for customizing ``Mapper`` behavior.
|
||||
"""Base implementation for :class:`.Mapper` event hooks.
|
||||
|
||||
.. note:: :class:`.MapperExtension` is deprecated. Please
|
||||
refer to :func:`.event.listen` as well as
|
||||
:class:`.MapperEvents`.
|
||||
|
||||
New extension classes subclass ``MapperExtension`` and are specified
|
||||
New extension classes subclass :class:`.MapperExtension` and are specified
|
||||
using the ``extension`` mapper() argument, which is a single
|
||||
``MapperExtension`` or a list of such. A single mapper
|
||||
can maintain a chain of ``MapperExtension`` objects. When a
|
||||
particular mapping event occurs, the corresponding method
|
||||
on each ``MapperExtension`` is invoked serially, and each method
|
||||
has the ability to halt the chain from proceeding further.
|
||||
:class:`.MapperExtension` or a list of such::
|
||||
|
||||
from sqlalchemy.orm.interfaces import MapperExtension
|
||||
|
||||
class MyExtension(MapperExtension):
|
||||
def before_insert(self, mapper, connection, instance):
|
||||
print "instance %s before insert !" % instance
|
||||
|
||||
m = mapper(User, users_table, extension=MyExtension())
|
||||
|
||||
A single mapper can maintain a chain of ``MapperExtension``
|
||||
objects. When a particular mapping event occurs, the
|
||||
corresponding method on each ``MapperExtension`` is invoked
|
||||
serially, and each method has the ability to halt the chain
|
||||
from proceeding further::
|
||||
|
||||
m = mapper(User, users_table, extension=[ext1, ext2, ext3])
|
||||
|
||||
Each ``MapperExtension`` method returns the symbol
|
||||
EXT_CONTINUE by default. This symbol generally means "move
|
||||
@@ -354,9 +370,28 @@ class MapperExtension(object):
|
||||
|
||||
class SessionExtension(object):
|
||||
|
||||
"""An extension hook object for Sessions. Subclasses may be
|
||||
installed into a Session (or sessionmaker) using the ``extension``
|
||||
keyword argument. """
|
||||
"""Base implementation for :class:`.Session` event hooks.
|
||||
|
||||
.. note:: :class:`.SessionExtension` is deprecated. Please
|
||||
refer to :func:`.event.listen` as well as
|
||||
:class:`.SessionEvents`.
|
||||
|
||||
Subclasses may be installed into a :class:`.Session` (or
|
||||
:func:`.sessionmaker`) using the ``extension`` keyword
|
||||
argument::
|
||||
|
||||
from sqlalchemy.orm.interfaces import SessionExtension
|
||||
|
||||
class MySessionExtension(SessionExtension):
|
||||
def before_commit(self, session):
|
||||
print "before commit!"
|
||||
|
||||
Session = sessionmaker(extension=MySessionExtension())
|
||||
|
||||
The same :class:`.SessionExtension` instance can be used
|
||||
with any number of sessions.
|
||||
|
||||
"""
|
||||
|
||||
def before_commit(self, session):
|
||||
"""Execute right before commit is called.
|
||||
@@ -432,11 +467,43 @@ class SessionExtension(object):
|
||||
|
||||
|
||||
class AttributeExtension(object):
|
||||
"""An event handler for individual attribute change events.
|
||||
"""Base implementation for :class:`.AttributeImpl` event hooks, events
|
||||
that fire upon attribute mutations in user code.
|
||||
|
||||
.. note:: :class:`.AttributeExtension` is deprecated. Please
|
||||
refer to :func:`.event.listen` as well as
|
||||
:class:`.AttributeEvents`.
|
||||
|
||||
.. note:: :class:`AttributeExtension` is deprecated. Please
|
||||
refer to :func:`event.listen` as well as
|
||||
:attr:`AttributeImpl.events`.
|
||||
:class:`.AttributeExtension` is used to listen for set,
|
||||
remove, and append events on individual mapped attributes.
|
||||
It is established on an individual mapped attribute using
|
||||
the `extension` argument, available on
|
||||
:func:`.column_property`, :func:`.relationship`, and
|
||||
others::
|
||||
|
||||
from sqlalchemy.orm.interfaces import AttributeExtension
|
||||
from sqlalchemy.orm import mapper, relationship, column_property
|
||||
|
||||
class MyAttrExt(AttributeExtension):
|
||||
def append(self, state, value, initiator):
|
||||
print "append event !"
|
||||
return value
|
||||
|
||||
def set(self, state, value, oldvalue, initiator):
|
||||
print "set event !"
|
||||
return value
|
||||
|
||||
mapper(SomeClass, sometable, properties={
|
||||
'foo':column_property(sometable.c.foo, extension=MyAttrExt()),
|
||||
'bar':relationship(Bar, extension=MyAttrExt())
|
||||
})
|
||||
|
||||
Note that the :class:`AttributeExtension` methods
|
||||
:meth:`~.AttributeExtension.append` and
|
||||
:meth:`~.AttributeExtension.set` need to return the
|
||||
``value`` parameter. The returned value is used as the
|
||||
effective value, and allows the extension to change what is
|
||||
ultimately persisted.
|
||||
|
||||
AttributeExtension is assembled within the descriptors associated
|
||||
with a mapped class.
|
||||
|
||||
+334
-105
@@ -133,45 +133,79 @@ class InstanceEvents(event.Events):
|
||||
"""
|
||||
|
||||
def on_resurrect(self, target):
|
||||
""""""
|
||||
"""Receive an object instance as it is 'resurrected' from
|
||||
garbage collection, which occurs when a "dirty" state falls
|
||||
out of scope."""
|
||||
|
||||
|
||||
class MapperEvents(event.Events):
|
||||
"""Define events specific to mappings.
|
||||
|
||||
|
||||
e.g.::
|
||||
|
||||
from sqlalchemy import event
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
# attach to a class
|
||||
def my_before_insert_listener(mapper, connection, target):
|
||||
# execute a stored procedure upon INSERT,
|
||||
# apply the value to the row to be inserted
|
||||
target.calculated_value = connection.scalar(
|
||||
"select my_special_function(%d)"
|
||||
% target.special_number)
|
||||
|
||||
# associate the listener function with SomeMappedClass,
|
||||
# to execute during the "on_before_insert" hook
|
||||
event.listen(my_before_insert_listener, 'on_before_insert', SomeMappedClass)
|
||||
|
||||
Available targets include mapped classes, instances of
|
||||
:class:`.Mapper` (i.e. returned by :func:`.mapper`,
|
||||
:func:`.class_mapper` and similar), as well as the
|
||||
:class:`.Mapper` class and :func:`.mapper` function itself
|
||||
for global event reception::
|
||||
|
||||
from sqlalchemy.orm import mapper
|
||||
|
||||
def some_listener(mapper, connection, target):
|
||||
log.debug("Instance %s being inserted" % target)
|
||||
|
||||
# attach to all mappers
|
||||
event.listen(some_listener, 'on_before_insert', mapper)
|
||||
|
||||
Mapper event listeners are propagated to subclass (inheriting)
|
||||
mappers unconditionally.
|
||||
Mapper events provide hooks into critical sections of the
|
||||
mapper, including those related to object instrumentation,
|
||||
object loading, and object persistence. In particular, the
|
||||
persistence methods :meth:`~.MapperEvents.on_before_insert`,
|
||||
and :meth:`~.MapperEvents.on_before_update` are popular
|
||||
places to augment the state being persisted - however, these
|
||||
methods operate with several significant restrictions. The
|
||||
user is encouraged to evaluate the
|
||||
:meth:`.SessionEvents.on_before_flush` and
|
||||
:meth:`.SessionEvents.on_after_flush` methods as more
|
||||
flexible and user-friendly hooks in which to apply
|
||||
additional database state during a flush.
|
||||
|
||||
Several modifiers are available to the listen() function.
|
||||
When using :class:`.MapperEvents`, several modifiers are
|
||||
available to the :func:`.event.listen` function.
|
||||
|
||||
:param propagate=False: When True, the event listener should
|
||||
be applied to all inheriting mappers as well.
|
||||
:param raw=False: When True, the "target" argument to the
|
||||
event, if applicable will be the :class:`.InstanceState` management
|
||||
be applied to all inheriting mappers as well as the
|
||||
mapper which is the target of this listener.
|
||||
:param raw=False: When True, the "target" argument passed
|
||||
to applicable event listener functions will be the
|
||||
instance's :class:`.InstanceState` management
|
||||
object, rather than the mapped instance itself.
|
||||
:param retval=False: when True, the user-defined event function
|
||||
must have a return value, the purpose of which is either to
|
||||
control subsequent event propagation, or to otherwise alter
|
||||
the operation in progress by the mapper. Possible values
|
||||
here are:
|
||||
the operation in progress by the mapper. Possible return
|
||||
values are:
|
||||
|
||||
* ``sqlalchemy.orm.interfaces.EXT_CONTINUE`` - continue event
|
||||
processing normally.
|
||||
* ``sqlalchemy.orm.interfaces.EXT_STOP`` - cancel all subsequent
|
||||
event handlers in the chain.
|
||||
* other values - the return value specified by specific listeners,
|
||||
such as "translate_row" or "create_instance".
|
||||
such as :meth:`~.MapperEvents.on_translate_row` or
|
||||
:meth:`~.MapperEvents.on_create_instance`.
|
||||
|
||||
"""
|
||||
|
||||
@@ -226,6 +260,10 @@ class MapperEvents(event.Events):
|
||||
This listener can generally only be applied to the :class:`.Mapper`
|
||||
class overall.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param class\_: the mapped class.
|
||||
|
||||
"""
|
||||
|
||||
def on_translate_row(self, mapper, context, row):
|
||||
@@ -236,13 +274,23 @@ class MapperEvents(event.Events):
|
||||
It is called when the mapper first receives a row, before
|
||||
the object identity or the instance itself has been derived
|
||||
from that row. The given row may or may not be a
|
||||
``RowProxy`` object - it will always be a dictionary-like
|
||||
:class:`.RowProxy` object - it will always be a dictionary-like
|
||||
object which contains mapped columns as keys. The
|
||||
returned object should also be a dictionary-like object
|
||||
which recognizes mapped columns as keys.
|
||||
|
||||
If the ultimate return value is EXT_CONTINUE, the row
|
||||
is not translated.
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param context: the :class:`.QueryContext`, which includes
|
||||
a handle to the current :class:`.Query` in progress as well
|
||||
as additional state information.
|
||||
:param row: the result row being handled. This may be
|
||||
an actual :class:`.RowProxy` or may be a dictionary containing
|
||||
:class:`.Column` objects as keys.
|
||||
:return: When configured with ``retval=True``, the function
|
||||
should return a dictionary-like row object, or ``EXT_CONTINUE``,
|
||||
indicating the original row should be used.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
@@ -254,20 +302,19 @@ class MapperEvents(event.Events):
|
||||
EXT_CONTINUE to indicate normal object creation should take place.
|
||||
This listener is typically registered with ``retval=True``.
|
||||
|
||||
mapper
|
||||
The mapper doing the operation
|
||||
|
||||
context
|
||||
The QueryContext generated from the Query.
|
||||
|
||||
row
|
||||
The result row from the database
|
||||
|
||||
class\_
|
||||
The class we are mapping.
|
||||
|
||||
return value
|
||||
A new object instance, or EXT_CONTINUE
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param context: the :class:`.QueryContext`, which includes
|
||||
a handle to the current :class:`.Query` in progress as well
|
||||
as additional state information.
|
||||
:param row: the result row being handled. This may be
|
||||
an actual :class:`.RowProxy` or may be a dictionary containing
|
||||
:class:`.Column` objects as keys.
|
||||
:param class\_: the mapped class.
|
||||
:return: When configured with ``retval=True``, the return value
|
||||
should be a newly created instance of the mapped class,
|
||||
or ``EXT_CONTINUE`` indicating that default object construction
|
||||
should take place.
|
||||
|
||||
"""
|
||||
|
||||
@@ -275,33 +322,32 @@ class MapperEvents(event.Events):
|
||||
result, **flags):
|
||||
"""Receive an object instance before that instance is appended
|
||||
to a result list.
|
||||
|
||||
This is a rarely used hook which can be used to alter
|
||||
the construction of a result list returned by :class:`.Query`.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param context: the :class:`.QueryContext`, which includes
|
||||
a handle to the current :class:`.Query` in progress as well
|
||||
as additional state information.
|
||||
:param row: the result row being handled. This may be
|
||||
an actual :class:`.RowProxy` or may be a dictionary containing
|
||||
:class:`.Column` objects as keys.
|
||||
:param target: the mapped instance being populated. If
|
||||
the event is configured with ``raw=True``, this will
|
||||
instead be the :class:`.InstanceState` state-management
|
||||
object associated with the instance.
|
||||
:param result: a list-like object where results are being
|
||||
appended.
|
||||
:param \**flags: Additional state information about the
|
||||
current handling of the row.
|
||||
:return: If this method is registered with ``retval=True``,
|
||||
a return value of ``EXT_STOP`` will prevent the instance
|
||||
from being appended to the given result list, whereas a
|
||||
return value of ``EXT_CONTINUE`` will result in the default
|
||||
behavior of appending the value to the result list.
|
||||
|
||||
If this method is registered with ``retval=True``,
|
||||
the append operation can be replaced. If any value other than
|
||||
EXT_CONTINUE is returned, result appending will not proceed for
|
||||
this instance, giving this extension an opportunity to do the
|
||||
appending itself, if desired.
|
||||
|
||||
mapper
|
||||
The mapper doing the operation.
|
||||
|
||||
selectcontext
|
||||
The QueryContext generated from the Query.
|
||||
|
||||
row
|
||||
The result row from the database.
|
||||
|
||||
target
|
||||
The object instance to be appended to the result, or
|
||||
the InstanceState if registered with ``raw=True``.
|
||||
|
||||
result
|
||||
List to which results are being appended.
|
||||
|
||||
\**flags
|
||||
extra information about the row, same as criterion in
|
||||
``create_row_processor()`` method of
|
||||
:class:`~sqlalchemy.orm.interfaces.MapperProperty`
|
||||
"""
|
||||
|
||||
|
||||
@@ -315,86 +361,265 @@ class MapperEvents(event.Events):
|
||||
unloaded attributes to be populated. The method may be called
|
||||
many times for a single instance, as multiple result rows are
|
||||
used to populate eagerly loaded collections.
|
||||
|
||||
If this listener is registered with ``retval=True`` and
|
||||
returns EXT_CONTINUE, instance population will
|
||||
proceed normally. If any other value or None is returned,
|
||||
instance population will not proceed, giving this extension an
|
||||
opportunity to populate the instance itself, if desired.
|
||||
|
||||
As of 0.5, most usages of this hook are obsolete. For a
|
||||
|
||||
Most usages of this hook are obsolete. For a
|
||||
generic "object has been newly created from a row" hook, use
|
||||
``reconstruct_instance()``, or the ``@orm.reconstructor``
|
||||
decorator.
|
||||
:meth:`.InstanceEvents.on_load`.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param context: the :class:`.QueryContext`, which includes
|
||||
a handle to the current :class:`.Query` in progress as well
|
||||
as additional state information.
|
||||
:param row: the result row being handled. This may be
|
||||
an actual :class:`.RowProxy` or may be a dictionary containing
|
||||
:class:`.Column` objects as keys.
|
||||
:param class\_: the mapped class.
|
||||
:return: When configured with ``retval=True``, a return
|
||||
value of ``EXT_STOP`` will bypass instance population by
|
||||
the mapper. A value of ``EXT_CONTINUE`` indicates that
|
||||
default instance population should take place.
|
||||
|
||||
"""
|
||||
|
||||
def on_before_insert(self, mapper, connection, target):
|
||||
"""Receive an object instance before that instance is inserted
|
||||
into its table.
|
||||
"""Receive an object instance before an INSERT statement
|
||||
is emitted corresponding to that instance.
|
||||
|
||||
This event is used to modify local, non-object related
|
||||
attributes on the instance before an INSERT occurs, as well
|
||||
as to emit additional SQL statements on the given
|
||||
connection.
|
||||
|
||||
The event is often called for a batch of objects of the
|
||||
same class before their INSERT statements are emitted at
|
||||
once in a later step. In the extremely rare case that
|
||||
this is not desirable, the :func:`.mapper` can be
|
||||
configured with ``batch=False``, which will cause
|
||||
batches of instances to be broken up into individual
|
||||
(and more poorly performing) event->persist->event
|
||||
steps.
|
||||
|
||||
Handlers should **not** modify any attributes which are
|
||||
mapped by :func:`.relationship`, nor should they attempt
|
||||
to make any modifications to the :class:`.Session` in
|
||||
this hook (including :meth:`.Session.add`,
|
||||
:meth:`.Session.delete`, etc.) - such changes will not
|
||||
take effect. For overall changes to the "flush plan",
|
||||
use :meth:`.SessionEvents.before_flush`.
|
||||
|
||||
This is a good place to set up primary key values and such
|
||||
that aren't handled otherwise.
|
||||
|
||||
Column-based attributes can be modified within this method
|
||||
which will result in the new value being inserted. However
|
||||
*no* changes to the overall flush plan can be made, and
|
||||
manipulation of the ``Session`` will not have the desired effect.
|
||||
To manipulate the ``Session`` within an extension, use
|
||||
``SessionExtension``.
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param connection: the :class:`.Connection` being used to
|
||||
emit INSERT statements for this instance. This
|
||||
provides a handle into the current transaction on the
|
||||
target database specific to this instance.
|
||||
:param target: the mapped instance being persisted. If
|
||||
the event is configured with ``raw=True``, this will
|
||||
instead be the :class:`.InstanceState` state-management
|
||||
object associated with the instance.
|
||||
:return: No return value is supported by this event.
|
||||
|
||||
"""
|
||||
|
||||
def on_after_insert(self, mapper, connection, target):
|
||||
"""Receive an object instance after that instance is inserted.
|
||||
"""Receive an object instance after an INSERT statement
|
||||
is emitted corresponding to that instance.
|
||||
|
||||
This event is used to modify in-Python-only
|
||||
state on the instance after an INSERT occurs, as well
|
||||
as to emit additional SQL statements on the given
|
||||
connection.
|
||||
|
||||
The event is often called for a batch of objects of the
|
||||
same class after their INSERT statements have been
|
||||
emitted at once in a previous step. In the extremely
|
||||
rare case that this is not desirable, the
|
||||
:func:`.mapper` can be configured with ``batch=False``,
|
||||
which will cause batches of instances to be broken up
|
||||
into individual (and more poorly performing)
|
||||
event->persist->event steps.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param connection: the :class:`.Connection` being used to
|
||||
emit INSERT statements for this instance. This
|
||||
provides a handle into the current transaction on the
|
||||
target database specific to this instance.
|
||||
:param target: the mapped instance being persisted. If
|
||||
the event is configured with ``raw=True``, this will
|
||||
instead be the :class:`.InstanceState` state-management
|
||||
object associated with the instance.
|
||||
:return: No return value is supported by this event.
|
||||
|
||||
"""
|
||||
|
||||
def on_before_update(self, mapper, connection, target):
|
||||
"""Receive an object instance before that instance is updated.
|
||||
"""Receive an object instance before an UPDATE statement
|
||||
is emitted corresponding to that instance.
|
||||
|
||||
Note that this method is called for all instances that are marked as
|
||||
"dirty", even those which have no net changes to their column-based
|
||||
attributes. An object is marked as dirty when any of its column-based
|
||||
attributes have a "set attribute" operation called or when any of its
|
||||
collections are modified. If, at update time, no column-based
|
||||
attributes have any net changes, no UPDATE statement will be issued.
|
||||
This means that an instance being sent to before_update is *not* a
|
||||
guarantee that an UPDATE statement will be issued (although you can
|
||||
affect the outcome here).
|
||||
This event is used to modify local, non-object related
|
||||
attributes on the instance before an UPDATE occurs, as well
|
||||
as to emit additional SQL statements on the given
|
||||
connection.
|
||||
|
||||
This method is called for all instances that are
|
||||
marked as "dirty", *even those which have no net changes
|
||||
to their column-based attributes*. An object is marked
|
||||
as dirty when any of its column-based attributes have a
|
||||
"set attribute" operation called or when any of its
|
||||
collections are modified. If, at update time, no
|
||||
column-based attributes have any net changes, no UPDATE
|
||||
statement will be issued. This means that an instance
|
||||
being sent to :meth:`~.MapperEvents.on_before_update` is
|
||||
*not* a guarantee that an UPDATE statement will be
|
||||
issued, although you can affect the outcome here by
|
||||
modifying attributes so that a net change in value does
|
||||
exist.
|
||||
|
||||
To detect if the column-based attributes on the object have net
|
||||
changes, and will therefore generate an UPDATE statement, use
|
||||
``object_session(instance).is_modified(instance,
|
||||
include_collections=False)``.
|
||||
|
||||
Column-based attributes can be modified within this method
|
||||
which will result in the new value being updated. However
|
||||
*no* changes to the overall flush plan can be made, and
|
||||
manipulation of the ``Session`` will not have the desired effect.
|
||||
To manipulate the ``Session`` within an extension, use
|
||||
``SessionExtension``.
|
||||
The event is often called for a batch of objects of the
|
||||
same class before their UPDATE statements are emitted at
|
||||
once in a later step. In the extremely rare case that
|
||||
this is not desirable, the :func:`.mapper` can be
|
||||
configured with ``batch=False``, which will cause
|
||||
batches of instances to be broken up into individual
|
||||
(and more poorly performing) event->persist->event
|
||||
steps.
|
||||
|
||||
Handlers should **not** modify any attributes which are
|
||||
mapped by :func:`.relationship`, nor should they attempt
|
||||
to make any modifications to the :class:`.Session` in
|
||||
this hook (including :meth:`.Session.add`,
|
||||
:meth:`.Session.delete`, etc.) - such changes will not
|
||||
take effect. For overall changes to the "flush plan",
|
||||
use :meth:`.SessionEvents.before_flush`.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param connection: the :class:`.Connection` being used to
|
||||
emit UPDATE statements for this instance. This
|
||||
provides a handle into the current transaction on the
|
||||
target database specific to this instance.
|
||||
:param target: the mapped instance being persisted. If
|
||||
the event is configured with ``raw=True``, this will
|
||||
instead be the :class:`.InstanceState` state-management
|
||||
object associated with the instance.
|
||||
:return: No return value is supported by this event.
|
||||
"""
|
||||
|
||||
def on_after_update(self, mapper, connection, target):
|
||||
"""Receive an object instance after that instance is updated.
|
||||
"""Receive an object instance after an UPDATE statement
|
||||
is emitted corresponding to that instance.
|
||||
|
||||
This event is used to modify in-Python-only
|
||||
state on the instance after an UPDATE occurs, as well
|
||||
as to emit additional SQL statements on the given
|
||||
connection.
|
||||
|
||||
This method is called for all instances that are
|
||||
marked as "dirty", *even those which have no net changes
|
||||
to their column-based attributes*, and for which
|
||||
no UPDATE statement has proceeded. An object is marked
|
||||
as dirty when any of its column-based attributes have a
|
||||
"set attribute" operation called or when any of its
|
||||
collections are modified. If, at update time, no
|
||||
column-based attributes have any net changes, no UPDATE
|
||||
statement will be issued. This means that an instance
|
||||
being sent to :meth:`~.MapperEvents.on_after_update` is
|
||||
*not* a guarantee that an UPDATE statement has been
|
||||
issued.
|
||||
|
||||
To detect if the column-based attributes on the object have net
|
||||
changes, and therefore resulted in an UPDATE statement, use
|
||||
``object_session(instance).is_modified(instance,
|
||||
include_collections=False)``.
|
||||
|
||||
The event is often called for a batch of objects of the
|
||||
same class after their UPDATE statements have been emitted at
|
||||
once in a previous step. In the extremely rare case that
|
||||
this is not desirable, the :func:`.mapper` can be
|
||||
configured with ``batch=False``, which will cause
|
||||
batches of instances to be broken up into individual
|
||||
(and more poorly performing) event->persist->event
|
||||
steps.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param connection: the :class:`.Connection` being used to
|
||||
emit UPDATE statements for this instance. This
|
||||
provides a handle into the current transaction on the
|
||||
target database specific to this instance.
|
||||
:param target: the mapped instance being persisted. If
|
||||
the event is configured with ``raw=True``, this will
|
||||
instead be the :class:`.InstanceState` state-management
|
||||
object associated with the instance.
|
||||
:return: No return value is supported by this event.
|
||||
|
||||
"""
|
||||
|
||||
def on_before_delete(self, mapper, connection, target):
|
||||
"""Receive an object instance before that instance is deleted.
|
||||
|
||||
Note that *no* changes to the overall flush plan can be made
|
||||
here; and manipulation of the ``Session`` will not have the
|
||||
desired effect. To manipulate the ``Session`` within an
|
||||
extension, use ``SessionExtension``.
|
||||
"""Receive an object instance before a DELETE statement
|
||||
is emitted corresponding to that instance.
|
||||
|
||||
This event is used to emit additional SQL statements on
|
||||
the given connection as well as to perform application
|
||||
specific bookkeeping related to a deletion event.
|
||||
|
||||
The event is often called for a batch of objects of the
|
||||
same class before their DELETE statements are emitted at
|
||||
once in a later step.
|
||||
|
||||
Handlers should **not** modify any attributes which are
|
||||
mapped by :func:`.relationship`, nor should they attempt
|
||||
to make any modifications to the :class:`.Session` in
|
||||
this hook (including :meth:`.Session.add`,
|
||||
:meth:`.Session.delete`, etc.) - such changes will not
|
||||
take effect. For overall changes to the "flush plan",
|
||||
use :meth:`.SessionEvents.before_flush`.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param connection: the :class:`.Connection` being used to
|
||||
emit DELETE statements for this instance. This
|
||||
provides a handle into the current transaction on the
|
||||
target database specific to this instance.
|
||||
:param target: the mapped instance being deleted. If
|
||||
the event is configured with ``raw=True``, this will
|
||||
instead be the :class:`.InstanceState` state-management
|
||||
object associated with the instance.
|
||||
:return: No return value is supported by this event.
|
||||
|
||||
"""
|
||||
|
||||
def on_after_delete(self, mapper, connection, target):
|
||||
"""Receive an object instance after that instance is deleted.
|
||||
"""Receive an object instance after a DELETE statement
|
||||
has been emitted corresponding to that instance.
|
||||
|
||||
This event is used to emit additional SQL statements on
|
||||
the given connection as well as to perform application
|
||||
specific bookkeeping related to a deletion event.
|
||||
|
||||
The event is often called for a batch of objects of the
|
||||
same class after their DELETE statements have been emitted at
|
||||
once in a previous step.
|
||||
|
||||
:param mapper: the :class:`.Mapper` which is the target
|
||||
of this event.
|
||||
:param connection: the :class:`.Connection` being used to
|
||||
emit DELETE statements for this instance. This
|
||||
provides a handle into the current transaction on the
|
||||
target database specific to this instance.
|
||||
:param target: the mapped instance being deleted. If
|
||||
the event is configured with ``raw=True``, this will
|
||||
instead be the :class:`.InstanceState` state-management
|
||||
object associated with the instance.
|
||||
:return: No return value is supported by this event.
|
||||
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
@@ -417,7 +642,7 @@ class AttributeEvents(event.Events):
|
||||
event.listen(my_set_listener, 'on_set',
|
||||
MyClass.somescalar, retval=True)
|
||||
|
||||
Several modifiers are available to the listen() function.
|
||||
Several modifiers are available to the :func:`~event.listen` function.
|
||||
|
||||
:param active_history=False: When True, indicates that the
|
||||
"on_set" event would like to receive the "old" value
|
||||
@@ -488,7 +713,9 @@ class AttributeEvents(event.Events):
|
||||
replaces it.
|
||||
:param initiator: the attribute implementation object
|
||||
which initiated this event.
|
||||
|
||||
:return: if the event was registered with ``retval=True``,
|
||||
the given value, or a new effective value, should be returned.
|
||||
|
||||
"""
|
||||
|
||||
def on_remove(self, target, value, initiator):
|
||||
@@ -500,7 +727,7 @@ class AttributeEvents(event.Events):
|
||||
:param value: the value being removed.
|
||||
:param initiator: the attribute implementation object
|
||||
which initiated this event.
|
||||
|
||||
:return: No return value is defined for this event.
|
||||
"""
|
||||
|
||||
def on_set(self, target, value, oldvalue, initiator):
|
||||
@@ -521,6 +748,8 @@ class AttributeEvents(event.Events):
|
||||
or expired.
|
||||
:param initiator: the attribute implementation object
|
||||
which initiated this event.
|
||||
:return: if the event was registered with ``retval=True``,
|
||||
the given value, or a new effective value, should be returned.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -616,6 +616,18 @@ class LoaderStrategy(object):
|
||||
class InstrumentationManager(object):
|
||||
"""User-defined class instrumentation extension.
|
||||
|
||||
:class:`.InstrumentationManager` can be subclassed in order
|
||||
to change
|
||||
how class instrumentation proceeds. This class exists for
|
||||
the purposes of integration with other object management
|
||||
frameworks which would like to entirely modify the
|
||||
instrumentation methodology of the ORM, and is not intended
|
||||
for regular usage. For interception of class instrumentation
|
||||
events, see :class:`.InstrumentationEvents`.
|
||||
|
||||
For an example of :class:`.InstrumentationManager`, see the
|
||||
example :ref:`examples_instrumentation`.
|
||||
|
||||
The API for this class should be considered as semi-stable,
|
||||
and may change slightly with new releases.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user