ORM Events

The ORM includes a wide variety of hooks available for subscription.

For an introduction to the most commonly used ORM events, see the sectionTracking Object and Session Changes with Events. The event system in general is discussedat Events. Non-ORM events such as those regarding connectionsand low-level statement execution are described in Core Events.

Attribute Events

Define events for object attributes.

These are typically defined on the class-bound descriptor for thetarget class.

e.g.:

  1. from sqlalchemy import event
  2.  
  3. @event.listens_for(MyClass.collection, 'append', propagate=True)
  4. def my_append_listener(target, value, initiator):
  5. print("received append event for target: %s" % target)

Listeners have the option to return a possibly modified version of thevalue, when the AttributeEvents.retval flag is passed toevent.listen() or event.listens_for():

  1. def validate_phone(target, value, oldvalue, initiator):
  2. "Strip non-numeric characters from a phone number"
  3.  
  4. return re.sub(r'\D', '', value)
  5.  
  6. # setup listener on UserContact.phone attribute, instructing
  7. # it to use the return value
  8. listen(UserContact.phone, 'set', validate_phone, retval=True)

A validation function like the above can also raise an exceptionsuch as ValueError to halt the operation.

The AttributeEvents.propagate flag is also important whenapplying listeners to mapped classes that also have mapped subclasses,as when using mapper inheritance patterns:

  1. @event.listens_for(MySuperClass.attr, 'set', propagate=True)def receive_set(target, value, initiator): print("value set: %s" % target)

The full list of modifiers available to the event.listen()and event.listens_for() functions are below.

  • Parameters
    • active_history=False – When True, indicates that the“set” event would like to receive the “old” value beingreplaced unconditionally, even if this requires firing offdatabase loads. Note that active_history can also beset directly via column_property() andrelationship().

    • propagate=False – When True, the listener function willbe established not just for the class attribute given, butfor attributes of the same name on all current subclassesof that class, as well as all future subclasses of thatclass, using an additional listener that listens forinstrumentation events.

    • raw=False – When True, the “target” argument to theevent will be the InstanceState managementobject, rather than the mapped instance itself.

    • retval=False – when True, the user-defined eventlistening must return the “value” argument from thefunction. This gives the listening function the opportunityto change the value that is ultimately used for a “set”or “append” event.

  • append(target, value, initiator)

  • Receive a collection append event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'append')
  5. def receive_append(target, value, initiator):
  6. "listen for the 'append' event"
  7.  
  8. # ... (event handling logic) ...

The append event is invoked for each element as it is appendedto the collection. This occurs for single-item appends as wellas for a “bulk replace” operation.

  1. - Parameters
  2. -
  3. -

target – the object instance receiving the event.If the listener is registered with raw=True, this willbe the InstanceState object.

  1. -

value – the value being appended. If this listeneris registered with retval=True, the listenerfunction must return this value, or a new value whichreplaces it.

  1. -

initiator – An instance of attributes.Eventrepresenting the initiation of the event. May be modifiedfrom its original value by backref handlers in order to controlchained event propagation, as well as be inspected for informationabout the source of the event.

  1. - Returns
  2. -

if the event was registered with retval=True,the given value, or a new effective value, should be returned.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

AttributeEvents.bulk_replace()

  • bulkreplace(_target, values, initiator)
  • Receive a collection ‘bulk replace’ event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'bulk_replace')
  5. def receive_bulk_replace(target, values, initiator):
  6. "listen for the 'bulk_replace' event"
  7.  
  8. # ... (event handling logic) ...

This event is invoked for a sequence of values as they are incomingto a bulk collection set operation, which can bemodified in place before the values are treated as ORM objects.This is an “early hook” that runs before the bulk replace routineattempts to reconcile which objects are already present in thecollection and which are being removed by the net replace operation.

It is typical that this method be combined with use of theAttributeEvents.append() event. When using both of theseevents, note that a bulk replace operation will invokethe AttributeEvents.append() event for all new items,even after AttributeEvents.bulk_replace() has been invokedfor the collection as a whole. In order to determine if anAttributeEvents.append() event is part of a bulk replace,use the symbol OP_BULK_REPLACE to test theincoming initiator:

  1. from sqlalchemy.orm.attributes import OP_BULK_REPLACE
  2.  
  3. @event.listens_for(SomeObject.collection, "bulk_replace")
  4. def process_collection(target, values, initiator):
  5. values[:] = [_make_value(value) for value in values]
  6.  
  7. @event.listens_for(SomeObject.collection, "append", retval=True)
  8. def process_collection(target, value, initiator):
  9. # make sure bulk_replace didn't already do it
  10. if initiator is None or initiator.op is not OP_BULK_REPLACE:
  11. return _make_value(value)
  12. else:
  13. return value

New in version 1.2.

  1. - Parameters
  2. -
  3. -

target – the object instance receiving the event.If the listener is registered with raw=True, this willbe the InstanceState object.

  1. -

value – a sequence (e.g. a list) of the values being set. Thehandler can modify this list in place.

  1. -

initiator – An instance of attributes.Eventrepresenting the initiation of the event.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

  • disposecollection(_target, collection, collection_adapter)
  • Receive a ‘collection dispose’ event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'dispose_collection')
  5. def receive_dispose_collection(target, collection, collection_adapter):
  6. "listen for the 'dispose_collection' event"
  7.  
  8. # ... (event handling logic) ...

This event is triggered for a collection-based attribute whena collection is replaced, that is:

  1. u1.addresses.append(a1)
  2.  
  3. u1.addresses = [a2, a3] # <- old collection is disposed

The old collection received will contain its previous contents.

Changed in version 1.2: The collection passed toAttributeEvents.dispose_collection() will now have itscontents before the dispose intact; previously, the collectionwould be empty.

New in version 1.0.0: the AttributeEvents.init_collection()and AttributeEvents.dispose_collection() events supersedethe collection.linker hook.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

  • initcollection(_target, collection, collection_adapter)
  • Receive a ‘collection init’ event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'init_collection')
  5. def receive_init_collection(target, collection, collection_adapter):
  6. "listen for the 'init_collection' event"
  7.  
  8. # ... (event handling logic) ...

This event is triggered for a collection-based attribute, whenthe initial “empty collection” is first generated for a blankattribute, as well as for when the collection is replaced witha new one, such as via a set event.

E.g., given that User.addresses is a relationship-basedcollection, the event is triggered here:

  1. u1 = User()
  2. u1.addresses.append(a1) # <- new collection

and also during replace operations:

  1. u1.addresses = [a2, a3] # <- new collection
  1. - Parameters
  2. -
  3. -

target – the object instance receiving the event.If the listener is registered with raw=True, this willbe the InstanceState object.

  1. -

collection – the new collection. This will always be generatedfrom what was specified asrelationship.collection_class, and will alwaysbe empty.

  1. -

collection_adapter – the CollectionAdapter that willmediate internal access to the collection.

New in version 1.0.0: the AttributeEvents.init_collection()and AttributeEvents.dispose_collection() events supersedethe orm.collection.linker hook.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

  • initscalar(_target, value, dict_)
  • Receive a scalar “init” event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'init_scalar')
  5. def receive_init_scalar(target, value, dict_):
  6. "listen for the 'init_scalar' event"
  7.  
  8. # ... (event handling logic) ...

This event is invoked when an uninitialized, unpersisted scalarattribute is accessed, e.g. read:

  1. x = my_object.some_attribute

The ORM’s default behavior when this occurs for an un-initializedattribute is to return the value None; note this differs fromPython’s usual behavior of raising AttributeError. Theevent here can be used to customize what value is actually returned,with the assumption that the event listener would be mirroringa default generator that is configured on the Core Columnobject as well.

Since a default generator on a Column might also producea changing value such as a timestamp, theAttributeEvents.init_scalar()event handler can also be used to set the newly returned value, sothat a Core-level default generation function effectively fires offonly once, but at the moment the attribute is accessed on thenon-persisted object. Normally, no change to the object’s stateis made when an uninitialized attribute is accessed (much olderSQLAlchemy versions did in fact change the object’s state).

If a default generator on a column returned a particular constant,a handler might be used as follows:

  1. SOME_CONSTANT = 3.1415926
  2.  
  3. class MyClass(Base):
  4. # ...
  5.  
  6. some_attribute = Column(Numeric, default=SOME_CONSTANT)
  7.  
  8. @event.listens_for(
  9. MyClass.some_attribute, "init_scalar",
  10. retval=True, propagate=True)
  11. def _init_some_attribute(target, dict_, value):
  12. dict_['some_attribute'] = SOME_CONSTANT
  13. return SOME_CONSTANT

Above, we initialize the attribute MyClass.some_attribute to thevalue of SOME_CONSTANT. The above code includes the followingfeatures:

  1. -

By setting the value SOMECONSTANT in the given dict,we indicate that this value is to be persisted to the database.This supersedes the use of SOME_CONSTANT in the default generatorfor the Column. The active_column_defaults.pyexample given at Attribute Instrumentation illustrates usingthe same approach for a changing default, e.g. a timestampgenerator. In this particular example, it is not strictlynecessary to do this since SOME_CONSTANT would be part of theINSERT statement in either case.

  1. -

By establishing the retval=True flag, the value we returnfrom the function will be returned by the attribute getter.Without this flag, the event is assumed to be a passive observerand the return value of our function is ignored.

  1. -

The propagate=True flag is significant if the mapped classincludes inheriting subclasses, which would also make use of thisevent listener. Without this flag, an inheriting subclass willnot use our event handler.

In the above example, the attribute set eventAttributeEvents.set() as well as the related validation featureprovided by orm.validates is not invoked when we apply ourvalue to the given dict_. To have these events to invoke inresponse to our newly generated value, apply the value to the givenobject as a normal attribute set operation:

  1. SOME_CONSTANT = 3.1415926
  2.  
  3. @event.listens_for(
  4. MyClass.some_attribute, "init_scalar",
  5. retval=True, propagate=True)
  6. def _init_some_attribute(target, dict_, value):
  7. # will also fire off attribute set events
  8. target.some_attribute = SOME_CONSTANT
  9. return SOME_CONSTANT

When multiple listeners are set up, the generation of the valueis “chained” from one listener to the next by passing the valuereturned by the previous listener that specifies retval=Trueas the value argument of the next listener.

New in version 1.1.

  1. - Parameters
  2. -
  3. -

target – the object instance receiving the event.If the listener is registered with raw=True, this willbe the InstanceState object.

  1. -

value – the value that is to be returned before this eventlistener were invoked. This value begins as the value None,however will be the return value of the previous event handlerfunction if multiple listeners are present.

  1. -

dict_ – the attribute dictionary of this mapped object.This is normally the dict of the object, but in all casesrepresents the destination that the attribute system uses to getat the actual value of this attribute. Placing the value in thisdictionary has the effect that the value will be used in theINSERT statement generated by the unit of work.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

Attribute Instrumentation - see theactive_column_defaults.py example.

  • modified(target, initiator)
  • Receive a ‘modified’ event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'modified')
  5. def receive_modified(target, initiator):
  6. "listen for the 'modified' event"
  7.  
  8. # ... (event handling logic) ...

This event is triggered when the attributes.flag_modified()function is used to trigger a modify event on an attribute withoutany specific value being set.

New in version 1.2.

  1. - Parameters
  2. -
  3. -

target – the object instance receiving the event.If the listener is registered with raw=True, this willbe the InstanceState object.

  1. -

initiator – An instance of attributes.Eventrepresenting the initiation of the event.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

  • remove(target, value, initiator)
  • Receive a collection remove event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'remove')
  5. def receive_remove(target, value, initiator):
  6. "listen for the 'remove' event"
  7.  
  8. # ... (event handling logic) ...
  1. - Parameters
  2. -
  3. -

target – the object instance receiving the event.If the listener is registered with raw=True, this willbe the InstanceState object.

  1. -

value – the value being removed.

  1. -

initiator

An instance of attributes.Eventrepresenting the initiation of the event. May be modifiedfrom its original value by backref handlers in order to controlchained event propagation.

Changed in version 0.9.0: the initiator argument is nowpassed as a attributes.Event object, and may bemodified by backref handlers within a chain of backref-linkedevents.

  1. - Returns
  2. -

No return value is defined for this event.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

  • set(target, value, oldvalue, initiator)
  • Receive a scalar set event.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass.some_attribute, 'set')
  5. def receive_set(target, value, oldvalue, initiator):
  6. "listen for the 'set' event"
  7.  
  8. # ... (event handling logic) ...
  9.  
  10. # named argument style (new in 0.9)
  11. @event.listens_for(SomeClass.some_attribute, 'set', named=True)
  12. def receive_set(**kw):
  13. "listen for the 'set' event"
  14. target = kw['target']
  15. value = kw['value']
  16.  
  17. # ... (event handling logic) ...
  1. - Parameters
  2. -
  3. -

target – the object instance receiving the event.If the listener is registered with raw=True, this willbe the InstanceState object.

  1. -

value – the value being set. If this listeneris registered with retval=True, the listenerfunction must return this value, or a new value whichreplaces it.

  1. -

oldvalue – the previous value being replaced. Thismay also be the symbol NEVER_SET or NO_VALUE.If the listener is registered with active_history=True,the previous value of the attribute will be loaded fromthe database if the existing value is currently unloadedor expired.

  1. -

initiator

An instance of attributes.Eventrepresenting the initiation of the event. May be modifiedfrom its original value by backref handlers in order to controlchained event propagation.

Changed in version 0.9.0: the initiator argument is nowpassed as a attributes.Event object, and may bemodified by backref handlers within a chain of backref-linkedevents.

  1. - Returns
  2. -

if the event was registered with retval=True,the given value, or a new effective value, should be returned.

See also

AttributeEvents - background on listener options suchas propagation to subclasses.

Mapper Events

Define events specific to mappings.

e.g.:

  1. from sqlalchemy import event
  2.  
  3. def my_before_insert_listener(mapper, connection, target):
  4. # execute a stored procedure upon INSERT,
  5. # apply the value to the row to be inserted
  6. target.calculated_value = connection.scalar(
  7. "select my_special_function(%d)"
  8. % target.special_number)
  9.  
  10. # associate the listener function with SomeClass,
  11. # to execute during the "before_insert" hook
  12. event.listen(
  13. SomeClass, 'before_insert', my_before_insert_listener)

Available targets include:

  • mapped classes

  • unmapped superclasses of mapped or to-be-mapped classes(using the propagate=True flag)

  • Mapper objects

  • the Mapper class itself and the mapper()function indicate listening for all mappers.

Mapper events provide hooks into critical sections of themapper, including those related to object instrumentation,object loading, and object persistence. In particular, thepersistence methods before_insert(),and before_update() are popularplaces to augment the state being persisted - however, thesemethods operate with several significant restrictions. Theuser is encouraged to evaluate theSessionEvents.before_flush() andSessionEvents.after_flush() methods as moreflexible and user-friendly hooks in which to applyadditional database state during a flush.

When using MapperEvents, several modifiers areavailable to the event.listen() function.

  • Parameters
    • propagate=False – When True, the event listener shouldbe applied to all inheriting mappers and/or the mappers ofinheriting classes, as well as anymapper which is the target of this listener.

    • raw=False – When True, the “target” argument passedto applicable event listener functions will be theinstance’s InstanceState managementobject, rather than the mapped instance itself.

    • retval=False

when True, the user-defined event functionmust have a return value, the purpose of which is either tocontrol subsequent event propagation, or to otherwise alterthe operation in progress by the mapper. Possible returnvalues are:

  1. -

sqlalchemy.orm.interfaces.EXT_CONTINUE - continue eventprocessing normally.

  1. -

sqlalchemy.orm.interfaces.EXT_STOP - cancel all subsequentevent handlers in the chain.

  1. -

other values - the return value specified by specific listeners.

  • after_configured()
  • Called after a series of mappers have been configured.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'after_configured')
  5. def receive_after_configured():
  6. "listen for the 'after_configured' event"
  7.  
  8. # ... (event handling logic) ...

The MapperEvents.after_configured() event is invokedeach time the orm.configure_mappers() function isinvoked, after the function has completed its work.orm.configure_mappers() is typically invokedautomatically as mappings are first used, as well as each timenew mappers have been made available and new mapper use isdetected.

Contrast this event to the MapperEvents.mapper_configured()event, which is called on a per-mapper basis while the configurationoperation proceeds; unlike that event, when this event is invoked,all cross-configurations (e.g. backrefs) will also have been madeavailable for any mappers that were pending.Also contrast to MapperEvents.before_configured(),which is invoked before the series of mappers has been configured.

This event can only be applied to the Mapper classor mapper() function, and not to individual mappings ormapped classes. It is only invoked for all mappings as a whole:

  1. from sqlalchemy.orm import mapper
  2.  
  3. @event.listens_for(mapper, "after_configured")
  4. def go():
  5. # ...

Theoretically this event is called once perapplication, but is actually called any time new mappershave been affected by a orm.configure_mappers()call. If new mappings are constructed after existing ones havealready been used, this event will likely be called again. To ensurethat a particular event is only called once and no further, theonce=True argument (new in 0.9.4) can be applied:

  1. from sqlalchemy.orm import mapper
  2.  
  3. @event.listens_for(mapper, "after_configured", once=True)
  4. def go():
  5. # ...

See also

MapperEvents.before_mapper_configured()

MapperEvents.mapper_configured()

MapperEvents.before_configured()

  • afterdelete(_mapper, connection, target)
  • Receive an object instance after a DELETE statementhas been emitted corresponding to that instance.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'after_delete')
  5. def receive_after_delete(mapper, connection, target):
  6. "listen for the 'after_delete' event"
  7.  
  8. # ... (event handling logic) ...

This event is used to emit additional SQL statements onthe given connection as well as to perform applicationspecific bookkeeping related to a deletion event.

The event is often called for a batch of objects of thesame class after their DELETE statements have been emitted atonce in a previous step.

Warning

Mapper-level flush events only allow very limited operations,on attributes local to the row being operated upon only,as well as allowing any SQL to be emitted on the givenConnection. Please read fully the notesat Mapper-level Events for guidelines on usingthese methods; generally, the SessionEvents.before_flush()method should be preferred for general on-flush changes.

  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

connection – the Connection being used toemit DELETE statements for this instance. Thisprovides a handle into the current transaction on thetarget database specific to this instance.

  1. -

target – the mapped instance being deleted. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. - Returns
  2. -

No return value is supported by this event.

See also

Persistence Events

  • afterinsert(_mapper, connection, target)
  • Receive an object instance after an INSERT statementis emitted corresponding to that instance.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'after_insert')
  5. def receive_after_insert(mapper, connection, target):
  6. "listen for the 'after_insert' event"
  7.  
  8. # ... (event handling logic) ...

This event is used to modify in-Python-onlystate on the instance after an INSERT occurs, as wellas to emit additional SQL statements on the givenconnection.

The event is often called for a batch of objects of thesame class after their INSERT statements have beenemitted at once in a previous step. In the extremelyrare case that this is not desirable, themapper() can be configured with batch=False,which will cause batches of instances to be broken upinto individual (and more poorly performing)event->persist->event steps.

Warning

Mapper-level flush events only allow very limited operations,on attributes local to the row being operated upon only,as well as allowing any SQL to be emitted on the givenConnection. Please read fully the notesat Mapper-level Events for guidelines on usingthese methods; generally, the SessionEvents.before_flush()method should be preferred for general on-flush changes.

  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

connection – the Connection being used toemit INSERT statements for this instance. Thisprovides a handle into the current transaction on thetarget database specific to this instance.

  1. -

target – the mapped instance being persisted. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. - Returns
  2. -

No return value is supported by this event.

See also

Persistence Events

  • afterupdate(_mapper, connection, target)
  • Receive an object instance after an UPDATE statementis emitted corresponding to that instance.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'after_update')
  5. def receive_after_update(mapper, connection, target):
  6. "listen for the 'after_update' event"
  7.  
  8. # ... (event handling logic) ...

This event is used to modify in-Python-onlystate on the instance after an UPDATE occurs, as wellas to emit additional SQL statements on the givenconnection.

This method is called for all instances that aremarked as “dirty”, even those which have no net changesto their column-based attributes, and for whichno UPDATE statement has proceeded. An object is markedas dirty when any of its column-based attributes have a“set attribute” operation called or when any of itscollections are modified. If, at update time, nocolumn-based attributes have any net changes, no UPDATEstatement will be issued. This means that an instancebeing sent to after_update() isnot a guarantee that an UPDATE statement has beenissued.

To detect if the column-based attributes on the object have netchanges, and therefore resulted in an UPDATE statement, useobject_session(instance).is_modified(instance,include_collections=False).

The event is often called for a batch of objects of thesame class after their UPDATE statements have been emitted atonce in a previous step. In the extremely rare case thatthis is not desirable, the mapper() can beconfigured with batch=False, which will causebatches of instances to be broken up into individual(and more poorly performing) event->persist->eventsteps.

Warning

Mapper-level flush events only allow very limited operations,on attributes local to the row being operated upon only,as well as allowing any SQL to be emitted on the givenConnection. Please read fully the notesat Mapper-level Events for guidelines on usingthese methods; generally, the SessionEvents.before_flush()method should be preferred for general on-flush changes.

  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

connection – the Connection being used toemit UPDATE statements for this instance. Thisprovides a handle into the current transaction on thetarget database specific to this instance.

  1. -

target – the mapped instance being persisted. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. - Returns
  2. -

No return value is supported by this event.

See also

Persistence Events

  • before_configured()
  • Called before a series of mappers have been configured.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'before_configured')
  5. def receive_before_configured():
  6. "listen for the 'before_configured' event"
  7.  
  8. # ... (event handling logic) ...

The MapperEvents.before_configured() event is invokedeach time the orm.configure_mappers() function isinvoked, before the function has done any of its work.orm.configure_mappers() is typically invokedautomatically as mappings are first used, as well as each timenew mappers have been made available and new mapper use isdetected.

This event can only be applied to the Mapper classor mapper() function, and not to individual mappings ormapped classes. It is only invoked for all mappings as a whole:

  1. from sqlalchemy.orm import mapper
  2.  
  3. @event.listens_for(mapper, "before_configured")
  4. def go():
  5. # ...

Contrast this event to MapperEvents.after_configured(),which is invoked after the series of mappers has been configured,as well as MapperEvents.before_mapper_configured()and MapperEvents.mapper_configured(), which are both invokedon a per-mapper basis.

Theoretically this event is called once perapplication, but is actually called any time new mappersare to be affected by a orm.configure_mappers()call. If new mappings are constructed after existing ones havealready been used, this event will likely be called again. To ensurethat a particular event is only called once and no further, theonce=True argument (new in 0.9.4) can be applied:

  1. from sqlalchemy.orm import mapper
  2.  
  3. @event.listens_for(mapper, "before_configured", once=True)
  4. def go():
  5. # ...

New in version 0.9.3.

See also

MapperEvents.before_mapper_configured()

MapperEvents.mapper_configured()

MapperEvents.after_configured()

  • beforedelete(_mapper, connection, target)
  • Receive an object instance before a DELETE statementis emitted corresponding to that instance.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'before_delete')
  5. def receive_before_delete(mapper, connection, target):
  6. "listen for the 'before_delete' event"
  7.  
  8. # ... (event handling logic) ...

This event is used to emit additional SQL statements onthe given connection as well as to perform applicationspecific bookkeeping related to a deletion event.

The event is often called for a batch of objects of thesame class before their DELETE statements are emitted atonce in a later step.

Warning

Mapper-level flush events only allow very limited operations,on attributes local to the row being operated upon only,as well as allowing any SQL to be emitted on the givenConnection. Please read fully the notesat Mapper-level Events for guidelines on usingthese methods; generally, the SessionEvents.before_flush()method should be preferred for general on-flush changes.

  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

connection – the Connection being used toemit DELETE statements for this instance. Thisprovides a handle into the current transaction on thetarget database specific to this instance.

  1. -

target – the mapped instance being deleted. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. - Returns
  2. -

No return value is supported by this event.

See also

Persistence Events

  • beforeinsert(_mapper, connection, target)
  • Receive an object instance before an INSERT statementis emitted corresponding to that instance.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'before_insert')
  5. def receive_before_insert(mapper, connection, target):
  6. "listen for the 'before_insert' event"
  7.  
  8. # ... (event handling logic) ...

This event is used to modify local, non-object relatedattributes on the instance before an INSERT occurs, as wellas to emit additional SQL statements on the givenconnection.

The event is often called for a batch of objects of thesame class before their INSERT statements are emitted atonce in a later step. In the extremely rare case thatthis is not desirable, the mapper() can beconfigured with batch=False, which will causebatches of instances to be broken up into individual(and more poorly performing) event->persist->eventsteps.

Warning

Mapper-level flush events only allow very limited operations,on attributes local to the row being operated upon only,as well as allowing any SQL to be emitted on the givenConnection. Please read fully the notesat Mapper-level Events for guidelines on usingthese methods; generally, the SessionEvents.before_flush()method should be preferred for general on-flush changes.

  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

connection – the Connection being used toemit INSERT statements for this instance. Thisprovides a handle into the current transaction on thetarget database specific to this instance.

  1. -

target – the mapped instance being persisted. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. - Returns
  2. -

No return value is supported by this event.

See also

Persistence Events

  • beforemapper_configured(_mapper, class_)
  • Called right before a specific mapper is to be configured.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'before_mapper_configured')
  5. def receive_before_mapper_configured(mapper, class_):
  6. "listen for the 'before_mapper_configured' event"
  7.  
  8. # ... (event handling logic) ...

This event is intended to allow a specific mapper to be skipped duringthe configure step, by returning the orm.interfaces.EXT_SKIPsymbol which indicates to the configure_mappers() call that thisparticular mapper (or hierarchy of mappers, if propagate=True isused) should be skipped in the current configuration run. When one ormore mappers are skipped, the he “new mappers” flag will remain set,meaning the configure_mappers() function will continue to becalled when mappers are used, to continue to try to configure allavailable mappers.

In comparison to the other configure-level events,MapperEvents.before_configured(),MapperEvents.after_configured(), andMapperEvents.mapper_configured(), the:meth;.MapperEvents.before_mapper_configured event provides for ameaningful return value when it is registered with the retval=Trueparameter.

New in version 1.3.

e.g.:

  1. from sqlalchemy.orm import EXT_SKIP
  2.  
  3. Base = declarative_base()
  4.  
  5. DontConfigureBase = declarative_base()
  6.  
  7. @event.listens_for(
  8. DontConfigureBase,
  9. "before_mapper_configured", retval=True, propagate=True)
  10. def dont_configure(mapper, cls):
  11. return EXT_SKIP

See also

MapperEvents.before_configured()

MapperEvents.after_configured()

MapperEvents.mapper_configured()

  • beforeupdate(_mapper, connection, target)
  • Receive an object instance before an UPDATE statementis emitted corresponding to that instance.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'before_update')
  5. def receive_before_update(mapper, connection, target):
  6. "listen for the 'before_update' event"
  7.  
  8. # ... (event handling logic) ...

This event is used to modify local, non-object relatedattributes on the instance before an UPDATE occurs, as wellas to emit additional SQL statements on the givenconnection.

This method is called for all instances that aremarked as “dirty”, even those which have no net changesto their column-based attributes. An object is markedas dirty when any of its column-based attributes have a“set attribute” operation called or when any of itscollections are modified. If, at update time, nocolumn-based attributes have any net changes, no UPDATEstatement will be issued. This means that an instancebeing sent to before_update() isnot a guarantee that an UPDATE statement will beissued, although you can affect the outcome here bymodifying attributes so that a net change in value doesexist.

To detect if the column-based attributes on the object have netchanges, and will therefore generate an UPDATE statement, useobject_session(instance).is_modified(instance,include_collections=False).

The event is often called for a batch of objects of thesame class before their UPDATE statements are emitted atonce in a later step. In the extremely rare case thatthis is not desirable, the mapper() can beconfigured with batch=False, which will causebatches of instances to be broken up into individual(and more poorly performing) event->persist->eventsteps.

Warning

Mapper-level flush events only allow very limited operations,on attributes local to the row being operated upon only,as well as allowing any SQL to be emitted on the givenConnection. Please read fully the notesat Mapper-level Events for guidelines on usingthese methods; generally, the SessionEvents.before_flush()method should be preferred for general on-flush changes.

  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

connection – the Connection being used toemit UPDATE statements for this instance. Thisprovides a handle into the current transaction on thetarget database specific to this instance.

  1. -

target – the mapped instance being persisted. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. - Returns
  2. -

No return value is supported by this event.

See also

Persistence Events

  • instrumentclass(_mapper, class_)
  • Receive a class when the mapper is first constructed,before instrumentation is applied to the mapped class.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'instrument_class')
  5. def receive_instrument_class(mapper, class_):
  6. "listen for the 'instrument_class' event"
  7.  
  8. # ... (event handling logic) ...

This event is the earliest phase of mapper construction.Most attributes of the mapper are not yet initialized.

This listener can either be applied to the Mapperclass overall, or to any un-mapped class which serves as a basefor classes that will be mapped (using the propagate=True flag):

  1. Base = declarative_base()
  2.  
  3. @event.listens_for(Base, "instrument_class", propagate=True)
  4. def on_new_class(mapper, cls_):
  5. " ... "
  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

class_ – the mapped class.

  • mapperconfigured(_mapper, class_)
  • Called when a specific mapper has completed its own configurationwithin the scope of the configure_mappers() call.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'mapper_configured')
  5. def receive_mapper_configured(mapper, class_):
  6. "listen for the 'mapper_configured' event"
  7.  
  8. # ... (event handling logic) ...

The MapperEvents.mapper_configured() event is invokedfor each mapper that is encountered when theorm.configure_mappers() function proceeds through the currentlist of not-yet-configured mappers.orm.configure_mappers() is typically invokedautomatically as mappings are first used, as well as each timenew mappers have been made available and new mapper use isdetected.

When the event is called, the mapper should be in its finalstate, but not including backrefs that may be invoked fromother mappers; they might still be pending within theconfiguration operation. Bidirectional relationships thatare instead configured via theorm.relationship.back_populates argumentwill be fully available, since this style of relationship does notrely upon other possibly-not-configured mappers to know that theyexist.

For an event that is guaranteed to have all mappers readyto go including backrefs that are defined only on othermappings, use the MapperEvents.after_configured()event; this event invokes only after all known mappings have beenfully configured.

The MapperEvents.mapper_configured() event, unlikeMapperEvents.before_configured() orMapperEvents.after_configured(),is called for each mapper/class individually, and the mapper ispassed to the event itself. It also is called exactly once fora particular mapper. The event is therefore useful forconfigurational steps that benefit from being invoked just onceon a specific mapper basis, which don’t require that “backref”configurations are necessarily ready yet.

  1. - Parameters
  2. -
  3. -

mapper – the Mapper which is the targetof this event.

  1. -

class_ – the mapped class.

See also

MapperEvents.before_configured()

MapperEvents.after_configured()

MapperEvents.before_mapper_configured()

Instance Events

Define events specific to object lifecycle.

e.g.:

  1. from sqlalchemy import event
  2.  
  3. def my_load_listener(target, context):
  4. print "on load!"
  5.  
  6. event.listen(SomeClass, 'load', my_load_listener)

Available targets include:

  • mapped classes

  • unmapped superclasses of mapped or to-be-mapped classes(using the propagate=True flag)

  • Mapper objects

  • the Mapper class itself and the mapper()function indicate listening for all mappers.

Instance events are closely related to mapper events, butare more specific to the instance and its instrumentation,rather than its system of persistence.

When using InstanceEvents, several modifiers areavailable to the event.listen() function.

  • Parameters
    • propagate=False – When True, the event listener shouldbe applied to all inheriting classes as well as theclass which is the target of this listener.

    • raw=False – When True, the “target” argument passedto applicable event listener functions will be theinstance’s InstanceState managementobject, rather than the mapped instance itself.

  • expire(target, attrs)

  • Receive an object instance after its attributes or some subsethave been expired.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'expire')
  5. def receive_expire(target, attrs):
  6. "listen for the 'expire' event"
  7.  
  8. # ... (event handling logic) ...

‘keys’ is a list of attribute names. If None, the entirestate was expired.

  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

attrs – sequence of attributenames which were expired, or None if all attributes wereexpired.

  • firstinit(_manager, cls)
  • Called when the first instance of a particular mapping is called.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'first_init')
  5. def receive_first_init(manager, cls):
  6. "listen for the 'first_init' event"
  7.  
  8. # ... (event handling logic) ...

This event is called when the init method of a classis called the first time for that particular class. The eventinvokes before init actually proceeds as well as beforethe InstanceEvents.init() event is invoked.

  • init(target, args, kwargs)
  • Receive an instance when its constructor is called.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'init')
  5. def receive_init(target, args, kwargs):
  6. "listen for the 'init' event"
  7.  
  8. # ... (event handling logic) ...

This method is only called during a userland construction ofan object, in conjunction with the object’s constructor, e.g.its init method. It is not called when an object isloaded from the database; see the InstanceEvents.load()event in order to intercept a database load.

The event is called before the actual init constructorof the object is called. The kwargs dictionary may bemodified in-place in order to affect what is passed toinit.

  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

args – positional arguments passed to the init method.This is passed as a tuple and is currently immutable.

  1. -

kwargs – keyword arguments passed to the init method.This structure can be altered in place.

See also

InstanceEvents.init_failure()

InstanceEvents.load()

  • initfailure(_target, args, kwargs)
  • Receive an instance when its constructor has been called,and raised an exception.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'init_failure')
  5. def receive_init_failure(target, args, kwargs):
  6. "listen for the 'init_failure' event"
  7.  
  8. # ... (event handling logic) ...

This method is only called during a userland construction ofan object, in conjunction with the object’s constructor, e.g.its init method. It is not called when an object is loadedfrom the database.

The event is invoked after an exception raised by the initmethod is caught. After the eventis invoked, the original exception is re-raised outwards, so thatthe construction of the object still raises an exception. Theactual exception and stack trace raised should be present insys.exc_info().

  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

args – positional arguments that were passed to the initmethod.

  1. -

kwargs – keyword arguments that were passed to the initmethod.

See also

InstanceEvents.init()

InstanceEvents.load()

  • load(target, context)
  • Receive an object instance after it has been created vianew, and after initial attribute population hasoccurred.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'load')
  5. def receive_load(target, context):
  6. "listen for the 'load' event"
  7.  
  8. # ... (event handling logic) ...

This typically occurs when the instance is created based onincoming result rows, and is only called once for thatinstance’s lifetime.

Note that during a result-row load, this method is called uponthe first row received for this instance. Note that someattributes and collections may or may not be loaded or eveninitialized, depending on what’s present in the result rows.

The InstanceEvents.load() event is also available in aclass-method decorator format called orm.reconstructor().

  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

context – the QueryContext corresponding to thecurrent Query in progress. This argument may beNone if the load does not correspond to a Query,such as during Session.merge().

See also

InstanceEvents.init()

InstanceEvents.refresh()

SessionEvents.loaded_as_persistent()

Constructors and Object Initialization

  • pickle(target, state_dict)
  • Receive an object instance when its associated state isbeing pickled.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'pickle')
  5. def receive_pickle(target, state_dict):
  6. "listen for the 'pickle' event"
  7.  
  8. # ... (event handling logic) ...
  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

state_dict – the dictionary returned byInstanceState.getstate, containing the stateto be pickled.

  • refresh(target, context, attrs)
  • Receive an object instance after one or more attributes havebeen refreshed from a query.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'refresh')
  5. def receive_refresh(target, context, attrs):
  6. "listen for the 'refresh' event"
  7.  
  8. # ... (event handling logic) ...

Contrast this to the InstanceEvents.load() method, whichis invoked when the object is first loaded from a query.

  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

context – the QueryContext corresponding to thecurrent Query in progress.

  1. -

attrs – sequence of attribute names whichwere populated, or None if all column-mapped, non-deferredattributes were populated.

See also

InstanceEvents.load()

  • refreshflush(_target, flush_context, attrs)
  • Receive an object instance after one or more attributes havebeen refreshed within the persistence of the object.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'refresh_flush')
  5. def receive_refresh_flush(target, flush_context, attrs):
  6. "listen for the 'refresh_flush' event"
  7.  
  8. # ... (event handling logic) ...

This event is the same as InstanceEvents.refresh() exceptit is invoked within the unit of work flush process, and the valueshere typically come from the process of handling an INSERT orUPDATE, such as via the RETURNING clause or from Python-side defaultvalues.

New in version 1.0.5.

  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

flush_context – Internal UOWTransaction objectwhich handles the details of the flush.

  1. -

attrs – sequence of attribute names whichwere populated.

  • unpickle(target, state_dict)
  • Receive an object instance after its associated state hasbeen unpickled.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeClass, 'unpickle')
  5. def receive_unpickle(target, state_dict):
  6. "listen for the 'unpickle' event"
  7.  
  8. # ... (event handling logic) ...
  1. - Parameters
  2. -
  3. -

target – the mapped instance. Ifthe event is configured with raw=True, this willinstead be the InstanceState state-managementobject associated with the instance.

  1. -

state_dict – the dictionary sent toInstanceState.setstate, containing the statedictionary which was pickled.

Session Events

Define events specific to Session lifecycle.

e.g.:

  1. from sqlalchemy import event
  2. from sqlalchemy.orm import sessionmaker
  3.  
  4. def my_before_commit(session):
  5. print "before commit!"
  6.  
  7. Session = sessionmaker()
  8.  
  9. event.listen(Session, "before_commit", my_before_commit)

The listen() function will acceptSession objects as well as the return resultof sessionmaker() and scoped_session().

Additionally, it accepts the Session class whichwill apply listeners to all Session instancesglobally.

  • afterattach(_session, instance)
  • Execute after an instance is attached to a session.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_attach')
  5. def receive_after_attach(session, instance):
  6. "listen for the 'after_attach' event"
  7.  
  8. # ... (event handling logic) ...

This is called after an add, delete or merge.

Note

As of 0.8, this event fires off after the itemhas been fully associated with the session, which isdifferent than previous releases. For eventhandlers that require the object not yetbe part of session state (such as handlers whichmay autoflush while the target object is notyet complete) consider thenew before_attach() event.

See also

before_attach()

Object Lifecycle Events

  • afterbegin(_session, transaction, connection)
  • Execute after a transaction is begun on a connection

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_begin')
  5. def receive_after_begin(session, transaction, connection):
  6. "listen for the 'after_begin' event"
  7.  
  8. # ... (event handling logic) ...
  1. - Parameters
  2. -
  3. -

session – The target Session.

  1. -

transaction – The SessionTransaction.

  1. -

connection – The Connection objectwhich will be used for SQL statements.

See also

before_commit()

after_commit()

after_transaction_create()

after_transaction_end()

  • afterbulk_delete(_delete_context)
  • Execute after a bulk delete operation to the session.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style (arguments as of 0.9)
  4. @event.listens_for(SomeSessionOrFactory, 'after_bulk_delete')
  5. def receive_after_bulk_delete(delete_context):
  6. "listen for the 'after_bulk_delete' event"
  7.  
  8. # ... (event handling logic) ...
  9.  
  10. # DEPRECATED calling style (pre-0.9, will be removed in a future release)
  11. @event.listens_for(SomeSessionOrFactory, 'after_bulk_delete')
  12. def receive_after_bulk_delete(session, query, query_context, result):
  13. "listen for the 'after_bulk_delete' event"
  14.  
  15. # ... (event handling logic) ...

Deprecated since version 0.9: The SessionEvents.after_bulk_delete event now accepts the arguments delete_context.Support for listener functions which accept the previous argument signature(s) listed above as “deprecated” will be removed in a future release.

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

  1. - Parameters
  2. -

delete_context

a “delete context” object which containsdetails about the update, including these attributes:

  • session - the Session involved

  • query -the Query object that this update operationwas called upon.

  • context The QueryContext object, correspondingto the invocation of an ORM query.

  • result the ResultProxy returned as a result of thebulk DELETE operation.

See also

QueryEvents.before_compile_delete()

SessionEvents.after_bulk_update()

  • afterbulk_update(_update_context)
  • Execute after a bulk update operation to the session.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style (arguments as of 0.9)
  4. @event.listens_for(SomeSessionOrFactory, 'after_bulk_update')
  5. def receive_after_bulk_update(update_context):
  6. "listen for the 'after_bulk_update' event"
  7.  
  8. # ... (event handling logic) ...
  9.  
  10. # DEPRECATED calling style (pre-0.9, will be removed in a future release)
  11. @event.listens_for(SomeSessionOrFactory, 'after_bulk_update')
  12. def receive_after_bulk_update(session, query, query_context, result):
  13. "listen for the 'after_bulk_update' event"
  14.  
  15. # ... (event handling logic) ...

Deprecated since version 0.9: The SessionEvents.after_bulk_update event now accepts the arguments update_context.Support for listener functions which accept the previous argument signature(s) listed above as “deprecated” will be removed in a future release.

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

  1. - Parameters
  2. -

update_context

an “update context” object which containsdetails about the update, including these attributes:

  • session - the Session involved

  • query -the Query object that this update operationwas called upon.

  • values The “values” dictionary that was passed toQuery.update().

  • context The QueryContext object, correspondingto the invocation of an ORM query.

  • result the ResultProxy returned as a result of thebulk UPDATE operation.

See also

QueryEvents.before_compile_update()

SessionEvents.after_bulk_delete()

  • aftercommit(_session)
  • Execute after a commit has occurred.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_commit')
  5. def receive_after_commit(session):
  6. "listen for the 'after_commit' event"
  7.  
  8. # ... (event handling logic) ...

Note

The after_commit() hook is not per-flush,that is, the Session can emit SQL to the databasemany times within the scope of a transaction.For interception of these events, use thebefore_flush(),after_flush(), orafter_flush_postexec()events.

Note

The Session is not in an active transactionwhen the after_commit() event is invoked,and therefore can not emit SQL. To emit SQL corresponding toevery transaction, use the before_commit()event.

  1. - Parameters
  2. -

session – The target Session.

See also

before_commit()

after_begin()

after_transaction_create()

after_transaction_end()

  • afterflush(_session, flush_context)
  • Execute after flush has completed, but before commit has beencalled.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_flush')
  5. def receive_after_flush(session, flush_context):
  6. "listen for the 'after_flush' event"
  7.  
  8. # ... (event handling logic) ...

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

Warning

This event runs after the Session has emittedSQL to modify the database, but before it has altered itsinternal state to reflect those changes, including that newlyinserted objects are placed into the identity map. ORM operationsemitted within this event such as loads of related itemsmay produce new identity map entries that will immediatelybe replaced, sometimes causing confusing results. SQLAlchemy willemit a warning for this condition as of version 1.3.9.

  1. - Parameters
  2. -
  3. -

session – The target Session.

  1. -

flush_context – Internal UOWTransaction objectwhich handles the details of the flush.

See also

before_flush()

after_flush_postexec()

Persistence Events

  • afterflush_postexec(_session, flush_context)
  • Execute after flush has completed, and after the post-execstate occurs.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_flush_postexec')
  5. def receive_after_flush_postexec(session, flush_context):
  6. "listen for the 'after_flush_postexec' event"
  7.  
  8. # ... (event handling logic) ...

This will be when the ‘new’, ‘dirty’, and ‘deleted’ lists are intheir final state. An actual commit() may or may not haveoccurred, depending on whether or not the flush started its owntransaction or participated in a larger transaction.

  1. - Parameters
  2. -
  3. -

session – The target Session.

  1. -

flush_context – Internal UOWTransaction objectwhich handles the details of the flush.

See also

before_flush()

after_flush()

Persistence Events

  • afterrollback(_session)
  • Execute after a real DBAPI rollback has occurred.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_rollback')
  5. def receive_after_rollback(session):
  6. "listen for the 'after_rollback' event"
  7.  
  8. # ... (event handling logic) ...

Note that this event only fires when the actual rollback againstthe database occurs - it does not fire each time theSession.rollback() method is called, if the underlyingDBAPI transaction has already been rolled back. In manycases, the Session will not be inan “active” state during this event, as the currenttransaction is not valid. To acquire a Sessionwhich is active after the outermost rollback has proceeded,use the SessionEvents.after_soft_rollback() event, checking theSession.is_active flag.

  1. - Parameters
  2. -

session – The target Session.

  • aftersoft_rollback(_session, previous_transaction)
  • Execute after any rollback has occurred, including “soft”rollbacks that don’t actually emit at the DBAPI level.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_soft_rollback')
  5. def receive_after_soft_rollback(session, previous_transaction):
  6. "listen for the 'after_soft_rollback' event"
  7.  
  8. # ... (event handling logic) ...

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

The given Session can be used to invoke SQL andSession.query() operations after an outermost rollbackby first checking the Session.is_active flag:

  1. @event.listens_for(Session, "after_soft_rollback")def do_something(session, previous_transaction): if session.is_active: session.execute("select * from some_table")

  1. - Parameters
  2. -
  3. -

session – The target Session.

  1. -

previous_transaction – The SessionTransactiontransactional marker object which was just closed. The currentSessionTransaction for the given Session isavailable via the Session.transaction attribute.

  • aftertransaction_create(_session, transaction)
  • Execute when a new SessionTransaction is created.

Example argument forms:

  1. from sqlalchemy import event
  2.  
  3. # standard decorator style
  4. @event.listens_for(SomeSessionOrFactory, 'after_transaction_create')
  5. def receive_after_transaction_create(session, transaction):
  6. "listen for the 'after_transaction_create' event"
  7.  
  8. # ... (event handling logic) ...

This event differs from after_begin()in that it occurs for each SessionTransactionoverall, as opposed to when transactions are begunon individual database connections. It is also invokedfor nested transactions and subtransactions, and is alwaysmatched by a correspondingafter_transaction_end() event(assuming normal operation of the Session).

  1. - Parameters
  2. -
  3. -

session – the target Session.

  1. -

transaction

the target SessionTransaction.

To detect if this is the outermostSessionTransaction, as opposed to a “subtransaction” or aSAVEPOINT, test that the SessionTransaction.parent attributeis None:

  1. @event.listens_for(session, "after_transaction_create")def after_transaction_create(session, transaction): if transaction.parent is None:

  2.     # work with top-level transaction</pre>
  3. To detect if the SessionTransaction is a SAVEPOINT, use theSessionTransaction.nested attribute:

  4. @event.listens_for(session, "after_transaction_create")def after_transaction_create(session, transaction):    if transaction.nested:

  5.     # work with SAVEPOINT transaction</pre>
  6. See also

  7. SessionTransaction

  8. after_transaction_end()

      • aftertransaction_end(_session, transaction)
      • Execute when the span of a SessionTransaction ends.
    • Example argument forms:

    • from sqlalchemy import event
    • # standard decorator style
    • @event.listens_for(SomeSessionOrFactory, 'after_transaction_end')
    • def receive_after_transaction_end(session, transaction):
    •     "listen for the 'after_transaction_end' event"
    •     # ... (event handling logic) ...
    • This event differs from after_commit()in that it corresponds to all SessionTransactionobjects in use, including those for nested transactionsand subtransactions, and is always matched by a correspondingafter_transaction_create() event.

    • - Parameters
    • - 
    •   - 
    • session the target Session.

    •   - 
    • transaction

    • the target SessionTransaction.

    • To detect if this is the outermostSessionTransaction, as opposed to a subtransaction or aSAVEPOINT, test that the SessionTransaction.parent attributeis None:

    • @event.listens_for(session, "after_transaction_create")def after_transaction_end(session, transaction):    if transaction.parent is None:

    •     # work with top-level transaction</pre>
    • To detect if the SessionTransaction is a SAVEPOINT, use theSessionTransaction.nested attribute:

    • @event.listens_for(session, "after_transaction_create")def after_transaction_end(session, transaction):    if transaction.nested:

    •     # work with SAVEPOINT transaction</pre>
    • See also

    • SessionTransaction

    • after_transaction_create()

        • beforeattach(_session, instance)
        • Execute before an instance is attached to a session.
      • Example argument forms:

      • from sqlalchemy import event
      • # standard decorator style
      • @event.listens_for(SomeSessionOrFactory, 'before_attach')
      • def receive_before_attach(session, instance):
      •     "listen for the 'before_attach' event"
      •     # ... (event handling logic) ...
      • This is called before an add, delete or merge causesthe object to be part of the session.

      • See also

      • after_attach()

      • Object Lifecycle Events

          • beforecommit(_session)
          • Execute before commit is called.
        • Example argument forms:

        • from sqlalchemy import event
        • # standard decorator style
        • @event.listens_for(SomeSessionOrFactory, 'before_commit')
        • def receive_before_commit(session):
        •     "listen for the 'before_commit' event"
        •     # ... (event handling logic) ...
        • Note

        • The before_commit() hook is not per-flush,that is, the Session can emit SQL to the databasemany times within the scope of a transaction.For interception of these events, use thebefore_flush(),after_flush(), orafter_flush_postexec()events.

        • - Parameters
        • - 
        • session The target Session.

        • See also

        • after_commit()

        • after_begin()

        • after_transaction_create()

        • after_transaction_end()

            • beforeflush(_session, flush_context, instances)
            • Execute before flush process has started.
          • Example argument forms:

          • from sqlalchemy import event
          • # standard decorator style
          • @event.listens_for(SomeSessionOrFactory, 'before_flush')
          • def receive_before_flush(session, flush_context, instances):
          •     "listen for the 'before_flush' event"
          •     # ... (event handling logic) ...
          • - Parameters
          • - 
          •   - 
          • session The target Session.

          •   - 
          • flush_context Internal UOWTransaction objectwhich handles the details of the flush.

          •   - 
          • instances Usually None, this is the collection ofobjects which can be passed to the Session.flush() method(note this usage is deprecated).

          • See also

          • after_flush()

          • after_flush_postexec()

          • Persistence Events

              • deletedto_detached(_session, instance)
              • Intercept the deleted to detached transition for a specific object.
            • Example argument forms:

            • from sqlalchemy import event
            • # standard decorator style
            • @event.listens_for(SomeSessionOrFactory, 'deleted_to_detached')
            • def receive_deleted_to_detached(session, instance):
            •     "listen for the 'deleted_to_detached' event"
            •     # ... (event handling logic) ...
            • This event is invoked when a deleted object is evictedfrom the session. The typical case when this occurs is whenthe transaction for a Session in which the objectwas deleted is committed; the object moves from the deletedstate to the detached state.

            • It is also invoked for objects that were deleted in a flushwhen the Session.expunge_all() or Session.close()events are called, as well as if the object is individuallyexpunged from its deleted state via Session.expunge().

            • New in version 1.1.

            • See also

            • Object Lifecycle Events

                • deletedto_persistent(_session, instance)
                • Intercept the deleted to persistent transition for a specific object.
              • Example argument forms:

              • from sqlalchemy import event
              • # standard decorator style
              • @event.listens_for(SomeSessionOrFactory, 'deleted_to_persistent')
              • def receive_deleted_to_persistent(session, instance):
              •     "listen for the 'deleted_to_persistent' event"
              •     # ... (event handling logic) ...
              • This transition occurs only when an object thats been deletedsuccessfully in a flush is restored due to a call toSession.rollback(). The event is not called underany other circumstances.

              • New in version 1.1.

              • See also

              • Object Lifecycle Events

                  • detachedto_persistent(_session, instance)
                  • Intercept the detached to persistent transition for a specific object.
                • Example argument forms:

                • from sqlalchemy import event
                • # standard decorator style
                • @event.listens_for(SomeSessionOrFactory, 'detached_to_persistent')
                • def receive_detached_to_persistent(session, instance):
                •     "listen for the 'detached_to_persistent' event"
                •     # ... (event handling logic) ...
                • This event is a specialization of theSessionEvents.after_attach() event which is only invokedfor this specific transition. It is invoked typically during theSession.add() call, as well as during theSession.delete() call if the object was not previouslyassociated with theSession (note that an object marked as deleted remainsin the persistent state until the flush proceeds).

                • Note

                • If the object becomes persistent as part of a call toSession.delete(), the object is not yet marked asdeleted when this event is called. To detect deleted objects,check the deleted flag sent to theSessionEvents.persistent_to_detached() to event after theflush proceeds, or check the Session.deleted collectionwithin the SessionEvents.before_flush() event if deletedobjects need to be intercepted before the flush.

                • - Parameters
                • - 
                •   - 
                • session target Session

                •   - 
                • instance the ORM-mapped instance being operated upon.

                • New in version 1.1.

                • See also

                • Object Lifecycle Events

                    • loadedas_persistent(_session, instance)
                    • Intercept the loaded as persistent transition for a specific object.
                  • Example argument forms:

                  • from sqlalchemy import event
                  • # standard decorator style
                  • @event.listens_for(SomeSessionOrFactory, 'loaded_as_persistent')
                  • def receive_loaded_as_persistent(session, instance):
                  •     "listen for the 'loaded_as_persistent' event"
                  •     # ... (event handling logic) ...
                  • This event is invoked within the ORM loading process, and is invokedvery 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 integrateswith the other session lifecycle events smoothly. The objectis guaranteed to be present in the sessions identity map whenthis event is called.

                  • - Parameters
                  • - 
                  •   - 
                  • session target Session

                  •   - 
                  • instance the ORM-mapped instance being operated upon.

                  • New in version 1.1.

                  • See also

                  • Object Lifecycle Events

                      • pendingto_persistent(_session, instance)
                      • Intercept the pending to persistent”” transition for a specific object.
                    • Example argument forms:

                    • from sqlalchemy import event
                    • # standard decorator style
                    • @event.listens_for(SomeSessionOrFactory, 'pending_to_persistent')
                    • def receive_pending_to_persistent(session, instance):
                    •     "listen for the 'pending_to_persistent' event"
                    •     # ... (event handling logic) ...
                    • This event is invoked within the flush process, and issimilar to scanning the Session.new collection withinthe SessionEvents.after_flush() event. However, in thiscase the object has already been moved to the persistent statewhen the event is called.

                    • - Parameters
                    • - 
                    •   - 
                    • session target Session

                    •   - 
                    • instance the ORM-mapped instance being operated upon.

                    • New in version 1.1.

                    • See also

                    • Object Lifecycle Events

                        • pendingto_transient(_session, instance)
                        • Intercept the pending to transient transition for a specific object.
                      • Example argument forms:

                      • from sqlalchemy import event
                      • # standard decorator style
                      • @event.listens_for(SomeSessionOrFactory, 'pending_to_transient')
                      • def receive_pending_to_transient(session, instance):
                      •     "listen for the 'pending_to_transient' event"
                      •     # ... (event handling logic) ...
                      • This less common transition occurs when an pending object that hasnot been flushed is evicted from the session; this can occurwhen the Session.rollback() method rolls back the transaction,or when the Session.expunge() method is used.

                      • - Parameters
                      • - 
                      •   - 
                      • session target Session

                      •   - 
                      • instance the ORM-mapped instance being operated upon.

                      • New in version 1.1.

                      • See also

                      • Object Lifecycle Events

                          • persistentto_deleted(_session, instance)
                          • Intercept the persistent to deleted transition for a specific object.
                        • Example argument forms:

                        • from sqlalchemy import event
                        • # standard decorator style
                        • @event.listens_for(SomeSessionOrFactory, 'persistent_to_deleted')
                        • def receive_persistent_to_deleted(session, instance):
                        •     "listen for the 'persistent_to_deleted' event"
                        •     # ... (event handling logic) ...
                        • This event is invoked when a persistent objects identityis deleted from the database within a flush, however the objectstill remains associated with the Session until thetransaction completes.

                        • If the transaction is rolled back, the object moves againto the persistent state, and theSessionEvents.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 primarypublic interface to mark an object as deleted, many objectsget deleted due to cascade rules, which are not always determineduntil flush time. Therefore, theres no way to catchevery object that will be deleted until the flush has proceeded.the SessionEvents.persistent_to_deleted() event is thereforeinvoked at the end of a flush.

                        • New in version 1.1.

                        • See also

                        • Object Lifecycle Events

                            • persistentto_detached(_session, instance)
                            • Intercept the persistent to detached transition for a specific object.
                          • Example argument forms:

                          • from sqlalchemy import event
                          • # standard decorator style
                          • @event.listens_for(SomeSessionOrFactory, 'persistent_to_detached')
                          • def receive_persistent_to_detached(session, instance):
                          •     "listen for the 'persistent_to_detached' event"
                          •     # ... (event handling logic) ...
                          • This event is invoked when a persistent object is evictedfrom the session. There are many conditions that cause thisto happen, including:

                          • - 
                          • using a method such as Session.expunge()or Session.close()

                          • - 
                          • Calling the Session.rollback() method, when the objectwas part of an INSERT statement for that sessions transaction

                          • - Parameters
                          • - 
                          •   - 
                          • session target Session

                          •   - 
                          • instance the ORM-mapped instance being operated upon.

                          •   - 
                          • deleted boolean. If True, indicates this object movedto the detached state because it was marked as deleted and flushed.

                          • New in version 1.1.

                          • See also

                          • Object Lifecycle Events

                              • persistentto_transient(_session, instance)
                              • Intercept the persistent to transient transition for a specific object.
                            • Example argument forms:

                            • from sqlalchemy import event
                            • # standard decorator style
                            • @event.listens_for(SomeSessionOrFactory, 'persistent_to_transient')
                            • def receive_persistent_to_transient(session, instance):
                            •     "listen for the 'persistent_to_transient' event"
                            •     # ... (event handling logic) ...
                            • This less common transition occurs when an pending object that hashas been flushed is evicted from the session; this can occurwhen the Session.rollback() method rolls back the transaction.

                            • - Parameters
                            • - 
                            •   - 
                            • session target Session

                            •   - 
                            • instance the ORM-mapped instance being operated upon.

                            • New in version 1.1.

                            • See also

                            • Object Lifecycle Events

                                • transientto_pending(_session, instance)
                                • Intercept the transient to pending transition for a specific object.
                              • Example argument forms:

                              • from sqlalchemy import event
                              • # standard decorator style
                              • @event.listens_for(SomeSessionOrFactory, 'transient_to_pending')
                              • def receive_transient_to_pending(session, instance):
                              •     "listen for the 'transient_to_pending' event"
                              •     # ... (event handling logic) ...
                              • This event is a specialization of theSessionEvents.after_attach() event which is only invokedfor this specific transition. It is invoked typically during theSession.add() call.

                              • - Parameters
                              • - 
                              •   - 
                              • session target Session

                              •   - 
                              • instance the ORM-mapped instance being operated upon.

                              • New in version 1.1.

                              • See also

                              • Object Lifecycle Events

                              • Query Events

                                • Represent events within the construction of a Query object.

                                • The events here are intended to be used with an as-yet-unreleasedinspection system for Query. Some very basic operationsare possible now, however the inspection system is intended to allowcomplex query manipulations to be automated.

                                • New in version 1.0.0.

                                    • beforecompile(_query)
                                    • Receive the Query object before it is composed into acore Select object.
                                  • Example argument forms:

                                  • from sqlalchemy import event
                                  • # standard decorator style
                                  • @event.listens_for(SomeQuery, 'before_compile')
                                  • def receive_before_compile(query):
                                  •     "listen for the 'before_compile' event"
                                  •     # ... (event handling logic) ...
                                  • This event is intended to allow changes to the query given:

                                  • @event.listens_for(Query, "before_compile", retval=True)def no_deleted(query):    for desc in query.column_descriptions:        if desc['type'] is User:            entity = desc['entity']            query = query.filter(entity.deleted == False)    return query

                                  • The event should normally be listened with the retval=Trueparameter set, so that the modified query may be returned.

                                  • See also

                                  • QueryEvents.before_compile_update()

                                  • QueryEvents.before_compile_delete()

                                      • beforecompile_delete(_query, delete_context)
                                      • Allow modifications to the Query object withinQuery.delete().
                                    • Example argument forms:

                                    • from sqlalchemy import event
                                    • # standard decorator style
                                    • @event.listens_for(SomeQuery, 'before_compile_delete')
                                    • def receive_before_compile_delete(query, delete_context):
                                    •     "listen for the 'before_compile_delete' event"
                                    •     # ... (event handling logic) ...
                                    • Like the QueryEvents.before_compile() event, this eventshould be configured with retval=True, and the modifiedQuery object returned, as in

                                    • @event.listens_for(Query, "before_compile_delete", retval=True)def no_deleted(query, delete_context):    for desc in query.column_descriptions:        if desc['type'] is User:            entity = desc['entity']            query = query.filter(entity.deleted == False)    return query

                                    • - Parameters
                                    • - 
                                    •   - 
                                    • query a Query instance; this is alsothe .query attribute of the given delete contextobject.

                                    •   - 
                                    • delete_context a delete context object which isthe same kind of object as described inQueryEvents.after_bulk_delete.delete_context.

                                    • New in version 1.2.17.

                                    • See also

                                    • QueryEvents.before_compile()

                                    • QueryEvents.before_compile_update()

                                        • beforecompile_update(_query, update_context)
                                        • Allow modifications to the Query object withinQuery.update().
                                      • Example argument forms:

                                      • from sqlalchemy import event
                                      • # standard decorator style
                                      • @event.listens_for(SomeQuery, 'before_compile_update')
                                      • def receive_before_compile_update(query, update_context):
                                      •     "listen for the 'before_compile_update' event"
                                      •     # ... (event handling logic) ...
                                      • Like the QueryEvents.before_compile() event, if the eventis to be used to alter the Query object, it shouldbe configured with retval=True, and the modifiedQuery object returned, as in

                                      • @event.listens_for(Query, "before_compile_update", retval=True)def no_deleted(query, update_context):    for desc in query.column_descriptions:        if desc['type'] is User:            entity = desc['entity']            query = query.filter(entity.deleted == False)

                                      •         update_context.values[&#39;timestamp&#39;] = datetime.utcnow()
                                      • return query</pre>
                                      • The .values dictionary of the update context object can alsobe modified in place as illustrated above.

                                      • - Parameters
                                      • - 
                                      •   - 
                                      • query a Query instance; this is alsothe .query attribute of the given update contextobject.

                                      •   - 
                                      • update_context an update context object which isthe same kind of object as described inQueryEvents.after_bulk_update.update_context.The object has a .values attribute in an UPDATE context which isthe dictionary of parameters passed to Query.update(). Thisdictionary can be modified to alter the VALUES clause of theresulting UPDATE statement.

                                      • New in version 1.2.17.

                                      • See also

                                      • QueryEvents.before_compile()

                                      • QueryEvents.before_compile_delete()

                                      • Instrumentation Events

                                        Defines SQLAlchemys system of class instrumentation.

                                      • This module is usually not directly visible to user applications, butdefines a large part of the ORMs interactivity.

                                      • instrumentation.py deals with registration of end-user classesfor state tracking. It interacts closely with state.pyand attributes.py which establish per-instance and per-class-attributeinstrumentation, respectively.

                                      • The class instrumentation system can be customized on a per-classor global basis using the sqlalchemy.ext.instrumentationmodule, which provides the means to build and specifyalternate instrumentation forms.

                                        • Events related to class instrumentation events.

                                        • The listeners here support being established againstany new style class, that is any object that is a subclassof type’. Events will then be fired off for eventsagainst that class. If the propagate=True flag is passedto event.listen(), the event will fire off for subclassesof that class as well.

                                        • The Python type builtin is also accepted as a target,which when used has the effect of events being emittedfor all classes.

                                        • Note the propagate flag here is defaulted to True,unlike the other class level events where it defaultsto False. This means that new subclasses will alsobe the subject of these events, when a listeneris established on a superclass.

                                            • attributeinstrument(_cls, key, inst)
                                          • Example argument forms:

                                          • from sqlalchemy import event
                                          • # standard decorator style
                                          • @event.listens_for(SomeBaseClass, 'attribute_instrument')
                                          • def receive_attribute_instrument(cls, key, inst):
                                          •     "listen for the 'attribute_instrument' event"
                                          •     # ... (event handling logic) ...
                                          • Called when an attribute is instrumented.

                                              • classinstrument(_cls)
                                              • Called after the given class is instrumented.
                                            • Example argument forms:

                                            • from sqlalchemy import event
                                            • # standard decorator style
                                            • @event.listens_for(SomeBaseClass, 'class_instrument')
                                            • def receive_class_instrument(cls):
                                            •     "listen for the 'class_instrument' event"
                                            •     # ... (event handling logic) ...
                                            • To get at the ClassManager, usemanager_of_class().

                                                • classuninstrument(_cls)
                                                • Called before the given class is uninstrumented.
                                              • Example argument forms:

                                              • from sqlalchemy import event
                                              • # standard decorator style
                                              • @event.listens_for(SomeBaseClass, 'class_uninstrument')
                                              • def receive_class_uninstrument(cls):
                                              •     "listen for the 'class_uninstrument' event"
                                              •     # ... (event handling logic) ...
                                              • To get at the ClassManager, usemanager_of_class().