class documentation

class SessionEvents(event.Events):

Known subclasses: sqlalchemy.ext.asyncio.events.AsyncSessionEvents

View In Hierarchy

Define events specific to .Session lifecycle.

e.g.:

from sqlalchemy import event
from sqlalchemy.orm import sessionmaker

def my_before_commit(session):
    print("before commit!")

Session = sessionmaker()

event.listen(Session, "before_commit", my_before_commit)

The ~.event.listen function will accept .Session objects as well as the return result of ~.sessionmaker() and ~.scoped_session().

Additionally, it accepts the .Session class which will apply listeners to all .Session instances globally.

Parameters
raw=​False

When True, the "target" argument passed to applicable event listener functions that work on individual objects will be the instance's .InstanceState management object, rather than the mapped instance itself.

New in version 1.3.14.
restore_load_context=​False

Applies to the .SessionEvents.loaded_as_persistent event. Restores the loader context of the object when the event hook is complete, so that ongoing eager load operations continue to target the object appropriately. A warning is emitted if the object is moved to a new loader context from within this event if this flag is not set.

New in version 1.3.14.
Class Method ​_accept​_with Undocumented
Class Method ​_listen Undocumented
Method ​_lifecycle​_event Undocumented
Method after​_attach Execute after an instance is attached to a session.
Method after​_begin Execute after a transaction is begun on a connection
Method after​_bulk​_delete Execute after ORM DELETE against a WHERE expression has been invoked.
Method after​_bulk​_update Execute after an ORM UPDATE against a WHERE expression has been invoked.
Method after​_commit Execute after a commit has occurred.
Method after​_flush Execute after flush has completed, but before commit has been called.
Method after​_flush​_postexec Execute after flush has completed, and after the post-exec state occurs.
Method after​_rollback Execute after a real DBAPI rollback has occurred.
Method after​_soft​_rollback Execute after any rollback has occurred, including "soft" rollbacks that don't actually emit at the DBAPI level.
Method after​_transaction​_create Execute when a new .SessionTransaction is created.
Method after​_transaction​_end Execute when the span of a .SessionTransaction ends.
Method before​_attach Execute before an instance is attached to a session.
Method before​_commit Execute before commit is called.
Method before​_flush Execute before flush process has started.
Method deleted​_to​_detached Intercept the "deleted to detached" transition for a specific object.
Method deleted​_to​_persistent Intercept the "deleted to persistent" transition for a specific object.
Method detached​_to​_persistent Intercept the "detached to persistent" transition for a specific object.
Method do​_orm​_execute Intercept statement executions that occur in terms of a .Session.
Method loaded​_as​_persistent Intercept the "loaded as persistent" transition for a specific object.
Method pending​_to​_persistent Intercept the "pending to persistent"" transition for a specific object.
Method pending​_to​_transient Intercept the "pending to transient" transition for a specific object.
Method persistent​_to​_deleted Intercept the "persistent to deleted" transition for a specific object.
Method persistent​_to​_detached Intercept the "persistent to detached" transition for a specific object.
Method persistent​_to​_transient Intercept the "persistent to transient" transition for a specific object.
Method transient​_to​_pending Intercept the "transient to pending" transition for a specific object.
Class Variable ​_target​_class​_doc Undocumented

Inherited from Events:

Class Method ​_clear Undocumented
Class Method ​_remove Undocumented
Static Method ​_set​_dispatch Undocumented
@classmethod
def _accept_with(cls, target):
@classmethod
def _listen(cls, event_key, raw=False, restore_load_context=False, **kw):
def _lifecycle_event(fn):

Undocumented

@_lifecycle_event
def after_attach(self, session, instance):

Execute after an instance is attached to a session.

This is called after an add, delete or merge.

Note

As of 0.8, this event fires off after the item has been fully associated with the session, which is different than previous releases. For event handlers that require the object not yet be part of session state (such as handlers which may autoflush while the target object is not yet complete) consider the new .before_attach event.

See Also

~.SessionEvents.before_attach

:ref:`session_lifecycle_events`

def after_begin(self, session, transaction, connection):

Execute after a transaction is begun on a connection

See Also

~.SessionEvents.before_commit

~.SessionEvents.after_commit

~.SessionEvents.after_transaction_create

~.SessionEvents.after_transaction_end

Parameters
sessionThe target .Session.
transactionThe .SessionTransaction.
connectionThe _engine.Connection object which will be used for SQL statements.
@event._legacy_signature('0.9', ['session', 'query', 'query_context', 'result'], (lambda delete_context: (delete_context.session, delete_context.query, No...
def after_bulk_delete(self, delete_context):

Execute after ORM DELETE against a WHERE expression has been invoked.

This is called as a result of the _query.Query.delete method.

Changed in version 1.4: the update_context no longer has a QueryContext object associated with it.

See Also

.QueryEvents.before_compile_delete

.SessionEvents.after_bulk_update

Parameters
delete​_context

a "delete context" object which contains details about the update, including these attributes:

  • session - the .Session involved
  • query -the _query.Query object that this update operation was called upon.
  • result the _engine.CursorResult returned as a result of the bulk DELETE operation.
@event._legacy_signature('0.9', ['session', 'query', 'query_context', 'result'], (lambda update_context: (update_context.session, update_context.query, No...
def after_bulk_update(self, update_context):

Execute after an ORM UPDATE against a WHERE expression has been invoked.

This is called as a result of the _query.Query.update method.

Changed in version 1.4: the update_context no longer has a QueryContext object associated with it.

See Also

.QueryEvents.before_compile_update

.SessionEvents.after_bulk_delete

Parameters
update​_context

an "update context" object which contains details about the update, including these attributes:

  • session - the .Session involved
  • query -the _query.Query object that this update operation was called upon.
  • values The "values" dictionary that was passed to _query.Query.update.
  • result the _engine.CursorResult returned as a result of the bulk UPDATE operation.
def after_commit(self, session):

Execute after a commit has occurred.

Note

The ~.SessionEvents.after_commit hook is not per-flush, that is, the .Session can emit SQL to the database many times within the scope of a transaction. For interception of these events, use the ~.SessionEvents.before_flush, ~.SessionEvents.after_flush, or ~.SessionEvents.after_flush_postexec events.

Note

The .Session is not in an active transaction when the ~.SessionEvents.after_commit event is invoked, and therefore can not emit SQL. To emit SQL corresponding to every transaction, use the ~.SessionEvents.before_commit event.

See Also

~.SessionEvents.before_commit

~.SessionEvents.after_begin

~.SessionEvents.after_transaction_create

~.SessionEvents.after_transaction_end

Parameters
sessionThe target .Session.
def after_flush(self, session, flush_context):

Execute after flush has completed, but before commit has been called.

Note that the session's state is still in pre-flush, i.e. 'new', 'dirty', and 'deleted' lists still show pre-flush state as well as the history settings on instance attributes.

Warning

This event runs after the .Session has emitted SQL to modify the database, but before it has altered its internal state to reflect those changes, including that newly inserted objects are placed into the identity map. ORM operations emitted within this event such as loads of related items may produce new identity map entries that will immediately be replaced, sometimes causing confusing results. SQLAlchemy will emit a warning for this condition as of version 1.3.9.

See Also

~.SessionEvents.before_flush

~.SessionEvents.after_flush_postexec

:ref:`session_persistence_events`

Parameters
sessionThe target .Session.
flush​_contextInternal .UOWTransaction object which handles the details of the flush.
def after_flush_postexec(self, session, flush_context):

Execute after flush has completed, and after the post-exec state occurs.

This will be when the 'new', 'dirty', and 'deleted' lists are in their final state. An actual commit() may or may not have occurred, depending on whether or not the flush started its own transaction or participated in a larger transaction.

See Also

~.SessionEvents.before_flush

~.SessionEvents.after_flush

:ref:`session_persistence_events`

Parameters
sessionThe target .Session.
flush​_contextInternal .UOWTransaction object which handles the details of the flush.
def after_rollback(self, session):

Execute after a real DBAPI rollback has occurred.

Note that this event only fires when the actual rollback against the database occurs - it does not fire each time the .Session.rollback method is called, if the underlying DBAPI transaction has already been rolled back. In many cases, the .Session will not be in an "active" state during this event, as the current transaction is not valid. To acquire a .Session which is active after the outermost rollback has proceeded, use the .SessionEvents.after_soft_rollback event, checking the .Session.is_active flag.

Parameters
sessionThe target .Session.
def after_soft_rollback(self, session, previous_transaction):

Execute after any rollback has occurred, including "soft" rollbacks that don't actually emit at the DBAPI level.

This corresponds to both nested and outer rollbacks, i.e. the innermost rollback that calls the DBAPI's rollback() method, as well as the enclosing rollback calls that only pop themselves from the transaction stack.

The given .Session can be used to invoke SQL and .Session.query operations after an outermost rollback by first checking the .Session.is_active flag:

@event.listens_for(Session, "after_soft_rollback")
def do_something(session, previous_transaction):
    if session.is_active:
        session.execute("select * from some_table")
Parameters
sessionThe target .Session.
previous​_transactionThe .SessionTransaction transactional marker object which was just closed. The current .SessionTransaction for the given .Session is available via the .Session.transaction attribute.
def after_transaction_create(self, session, transaction):

Execute when a new .SessionTransaction is created.

This event differs from ~.SessionEvents.after_begin in that it occurs for each .SessionTransaction overall, as opposed to when transactions are begun on individual database connections. It is also invoked for nested transactions and subtransactions, and is always matched by a corresponding ~.SessionEvents.after_transaction_end event (assuming normal operation of the .Session).

See Also

.SessionTransaction

~.SessionEvents.after_transaction_end

Parameters
sessionthe target .Session.
transaction

the target .SessionTransaction.

To detect if this is the outermost .SessionTransaction, as opposed to a "subtransaction" or a SAVEPOINT, test that the .SessionTransaction.parent attribute is None:

@event.listens_for(session, "after_transaction_create")
def after_transaction_create(session, transaction):
    if transaction.parent is None:
        # work with top-level transaction

To detect if the .SessionTransaction is a SAVEPOINT, use the .SessionTransaction.nested attribute:

@event.listens_for(session, "after_transaction_create")
def after_transaction_create(session, transaction):
    if transaction.nested:
        # work with SAVEPOINT transaction
def after_transaction_end(self, session, transaction):

Execute when the span of a .SessionTransaction ends.

This event differs from ~.SessionEvents.after_commit in that it corresponds to all .SessionTransaction objects in use, including those for nested transactions and subtransactions, and is always matched by a corresponding ~.SessionEvents.after_transaction_create event.

See Also

.SessionTransaction

~.SessionEvents.after_transaction_create

Parameters
sessionthe target .Session.
transaction

the target .SessionTransaction.

To detect if this is the outermost .SessionTransaction, as opposed to a "subtransaction" or a SAVEPOINT, test that the .SessionTransaction.parent attribute is None:

@event.listens_for(session, "after_transaction_create")
def after_transaction_end(session, transaction):
    if transaction.parent is None:
        # work with top-level transaction

To detect if the .SessionTransaction is a SAVEPOINT, use the .SessionTransaction.nested attribute:

@event.listens_for(session, "after_transaction_create")
def after_transaction_end(session, transaction):
    if transaction.nested:
        # work with SAVEPOINT transaction
@_lifecycle_event
def before_attach(self, session, instance):

Execute before an instance is attached to a session.

This is called before an add, delete or merge causes the object to be part of the session.

See Also

~.SessionEvents.after_attach

:ref:`session_lifecycle_events`

def before_commit(self, session):

Execute before commit is called.

Note

The ~.SessionEvents.before_commit hook is not per-flush, that is, the .Session can emit SQL to the database many times within the scope of a transaction. For interception of these events, use the ~.SessionEvents.before_flush, ~.SessionEvents.after_flush, or ~.SessionEvents.after_flush_postexec events.

See Also

~.SessionEvents.after_commit

~.SessionEvents.after_begin

~.SessionEvents.after_transaction_create

~.SessionEvents.after_transaction_end

Parameters
sessionThe target .Session.
def before_flush(self, session, flush_context, instances):

Execute before flush process has started.

See Also

~.SessionEvents.after_flush

~.SessionEvents.after_flush_postexec

:ref:`session_persistence_events`

Parameters
sessionThe target .Session.
flush​_contextInternal .UOWTransaction object which handles the details of the flush.
instancesUsually None, this is the collection of objects which can be passed to the .Session.flush method (note this usage is deprecated).
@_lifecycle_event
def deleted_to_detached(self, session, instance):

Intercept the "deleted to detached" transition for a specific object.

This event is invoked when a deleted object is evicted from the session. The typical case when this occurs is when the transaction for a .Session in which the object was deleted is committed; the object moves from the deleted state to the detached state.

It is also invoked for objects that were deleted in a flush when the .Session.expunge_all or .Session.close events are called, as well as if the object is individually expunged from its deleted state via .Session.expunge.

New in version 1.1.
@_lifecycle_event
def deleted_to_persistent(self, session, instance):

Intercept the "deleted to persistent" transition for a specific object.

This transition occurs only when an object that's been deleted successfully in a flush is restored due to a call to .Session.rollback. The event is not called under any other circumstances.

New in version 1.1.
@_lifecycle_event
def detached_to_persistent(self, session, instance):

Intercept the "detached to persistent" transition for a specific object.

This event is a specialization of the .SessionEvents.after_attach event which is only invoked for this specific transition. It is invoked typically during the .Session.add call, as well as during the .Session.delete call if the object was not previously associated with the .Session (note that an object marked as "deleted" remains in the "persistent" state until the flush proceeds).

Note

If the object becomes persistent as part of a call to .Session.delete, the object is not yet marked as deleted when this event is called. To detect deleted objects, check the deleted flag sent to the .SessionEvents.persistent_to_detached to event after the flush proceeds, or check the .Session.deleted collection within the .SessionEvents.before_flush event if deleted objects need to be intercepted before the flush.

New in version 1.1.
Parameters
sessiontarget .Session
instancethe ORM-mapped instance being operated upon.
def do_orm_execute(self, orm_execute_state):

Intercept statement executions that occur in terms of a .Session.

This event is invoked for all top-level SQL statements invoked from the _orm.Session.execute method. As of SQLAlchemy 1.4, all ORM queries emitted on behalf of a _orm.Session will flow through this method, so this event hook provides the single point at which ORM queries of all types may be intercepted before they are invoked, and additionally to replace their execution with a different process.

This event is a do_ event, meaning it has the capability to replace the operation that the _orm.Session.execute method normally performs. The intended use for this includes sharding and result-caching schemes which may seek to invoke the same statement across multiple database connections, returning a result that is merged from each of them, or which don't invoke the statement at all, instead returning data from a cache.

The hook intends to replace the use of the Query._execute_and_instances method that could be subclassed prior to SQLAlchemy 1.4.

See Also

:ref:`session_execute_events` - top level documentation on how to use _orm.SessionEvents.do_orm_execute

.ORMExecuteState - the object passed to the _orm.SessionEvents.do_orm_execute event which contains all information about the statement to be invoked. It also provides an interface to extend the current statement, options, and parameters as well as an option that allows programmatic invocation of the statement at any point.

:ref:`examples_session_orm_events` - includes examples of using _orm.SessionEvents.do_orm_execute

:ref:`examples_caching` - an example of how to integrate Dogpile caching with the ORM _orm.Session making use of the _orm.SessionEvents.do_orm_execute event hook.

:ref:`examples_sharding` - the Horizontal Sharding example / extension relies upon the _orm.SessionEvents.do_orm_execute event hook to invoke a SQL statement on multiple backends and return a merged result.

New in version 1.4.
Parameters
orm​_execute​_statean instance of .ORMExecuteState which contains all information about the current execution, as well as helper functions used to derive other commonly required information. See that object for details.
@_lifecycle_event
def loaded_as_persistent(self, session, instance):

Intercept the "loaded as persistent" transition for a specific object.

This event is invoked within the ORM loading process, and is invoked very similarly to the .InstanceEvents.load event. However, the event here is linkable to a .Session class or instance, rather than to a mapper or class hierarchy, and integrates with the other session lifecycle events smoothly. The object is guaranteed to be present in the session's identity map when this event is called.

Note

This event is invoked within the loader process before eager loaders may have been completed, and the object's state may not be complete. Additionally, invoking row-level refresh operations on the object will place the object into a new loader context, interfering with the existing load context. See the note on .InstanceEvents.load for background on making use of the :paramref:`.SessionEvents.restore_load_context` parameter, which works in the same manner as that of :paramref:`.InstanceEvents.restore_load_context`, in order to resolve this scenario.

New in version 1.1.
Parameters
sessiontarget .Session
instancethe ORM-mapped instance being operated upon.
@_lifecycle_event
def pending_to_persistent(self, session, instance):

Intercept the "pending to persistent"" transition for a specific object.

This event is invoked within the flush process, and is similar to scanning the .Session.new collection within the .SessionEvents.after_flush event. However, in this case the object has already been moved to the persistent state when the event is called.

New in version 1.1.
Parameters
sessiontarget .Session
instancethe ORM-mapped instance being operated upon.
@_lifecycle_event
def pending_to_transient(self, session, instance):

Intercept the "pending to transient" transition for a specific object.

This less common transition occurs when an pending object that has not been flushed is evicted from the session; this can occur when the .Session.rollback method rolls back the transaction, or when the .Session.expunge method is used.

New in version 1.1.
Parameters
sessiontarget .Session
instancethe ORM-mapped instance being operated upon.
@_lifecycle_event
def persistent_to_deleted(self, session, instance):

Intercept the "persistent to deleted" transition for a specific object.

This event is invoked when a persistent object's identity is deleted from the database within a flush, however the object still remains associated with the .Session until the transaction completes.

If the transaction is rolled back, the object moves again to the persistent state, and the .SessionEvents.deleted_to_persistent event is called. If the transaction is committed, the object becomes detached, which will emit the .SessionEvents.deleted_to_detached event.

Note that while the .Session.delete method is the primary public interface to mark an object as deleted, many objects get deleted due to cascade rules, which are not always determined until flush time. Therefore, there's no way to catch every object that will be deleted until the flush has proceeded. the .SessionEvents.persistent_to_deleted event is therefore invoked at the end of a flush.

New in version 1.1.
@_lifecycle_event
def persistent_to_detached(self, session, instance):

Intercept the "persistent to detached" transition for a specific object.

This event is invoked when a persistent object is evicted from the session. There are many conditions that cause this to happen, including:

  • using a method such as .Session.expunge or .Session.close
  • Calling the .Session.rollback method, when the object was part of an INSERT statement for that session's transaction
New in version 1.1.
Parameters
sessiontarget .Session
instancethe ORM-mapped instance being operated upon.
deletedboolean. If True, indicates this object moved to the detached state because it was marked as deleted and flushed.
@_lifecycle_event
def persistent_to_transient(self, session, instance):

Intercept the "persistent to transient" transition for a specific object.

This less common transition occurs when an pending object that has has been flushed is evicted from the session; this can occur when the .Session.rollback method rolls back the transaction.

New in version 1.1.
Parameters
sessiontarget .Session
instancethe ORM-mapped instance being operated upon.
@_lifecycle_event
def transient_to_pending(self, session, instance):

Intercept the "transient to pending" transition for a specific object.

This event is a specialization of the .SessionEvents.after_attach event which is only invoked for this specific transition. It is invoked typically during the .Session.add call.

New in version 1.1.
Parameters
sessiontarget .Session
instancethe ORM-mapped instance being operated upon.
_target_class_doc: str =