ORM-Ereignisse

Die ORM umfasst eine Vielzahl von Hooks, die zur Abonnementierung verfügbar sind.

Eine Einführung in die am häufigsten verwendeten ORM-Ereignisse finden Sie im Abschnitt Verfolgen von Abfragen, Objekten und Session-Änderungen mit Ereignissen. Das Ereignissystem im Allgemeinen wird unter Events diskutiert. Nicht-ORM-Ereignisse, wie die bezüglich Verbindungen und der Ausführung von Low-Level-Statements, werden unter Core Events beschrieben.

Session-Ereignisse

Die grundlegendsten Ereignishooks sind auf der Ebene des ORM Session-Objekts verfügbar. Zu den Dingen, die hier abgefangen werden, gehören:

  • Persistence-Operationen – Der ORM-Flush-Prozess, der Änderungen an die Datenbank sendet, kann mithilfe von Ereignissen erweitert werden, die zu verschiedenen Zeitpunkten des Flushes ausgelöst werden, um die an die Datenbank gesendeten Daten zu ergänzen oder zu ändern oder um andere Dinge zuzulassen, wenn die Persistenz erfolgt. Lesen Sie mehr über Persistence-Ereignisse unter Persistence Events.

  • Objektlebenszyklus-Ereignisse – Hooks, wenn Objekte zu Sessions hinzugefügt, persistiert oder aus Sessions gelöscht werden. Lesen Sie mehr darüber unter Object Lifecycle Events.

  • Ausführungsereignisse – Als Teil des 2.0-Stils des Ausführungsmodells werden alle SELECT-Statements gegen ORM-Entitäten sowie Bulk-UPDATE- und DELETE-Statements außerhalb des Flush-Prozesses aus der Methode Session.execute() über die Methode SessionEvents.do_orm_execute() abgefangen. Lesen Sie mehr über dieses Ereignis unter Execute Events.

Lesen Sie unbedingt das Kapitel Verfolgen von Abfragen, Objekten und Session-Änderungen mit Ereignissen, um Kontext zu diesen Ereignissen zu erhalten.

Objektname Beschreibung

SessionEvents

Definieren Sie ereignisspezifische Session-Lebenszyklen.

class sqlalchemy.orm.SessionEvents

Definieren Sie ereignisspezifische Session-Lebenszyklen.

z. B.

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)

Die Funktion listen() akzeptiert Session-Objekte sowie das Rückergebnis von sessionmaker() und scoped_session().

Zusätzlich akzeptiert es die Session-Klasse, die Listener global auf alle Session-Instanzen anwendet.

Parameter:
  • raw=False

    Wenn True, ist das Argument „target“, das an zutreffende Ereignislistener-Funktionen übergeben wird, die auf einzelne Objekte angewendet werden, das Management-Objekt InstanceState der Instanz, anstatt der abgebildete Instanz selbst.

    Neu in Version 1.3.14.

  • restore_load_context=False

    Gilt für das Ereignis SessionEvents.loaded_as_persistent(). Stellt den Ladekontext des Objekts wieder her, wenn der Ereignishook abgeschlossen ist, sodass laufende Eager-Load-Vorgänge weiterhin auf das Objekt abzielen. Eine Warnung wird ausgegeben, wenn das Objekt aus diesem Ereignis in einen neuen Ladekontext verschoben wird, wenn dieses Flag nicht gesetzt ist.

    Neu in Version 1.3.14.

Klassensignatur

class sqlalchemy.orm.SessionEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.SessionEvents.after_attach(session: Session, instance: _O) None

Wird ausgeführt, nachdem eine Instanz an eine Session angehängt wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_attach')
def receive_after_attach(session, instance):
    "listen for the 'after_attach' event"

    # ... (event handling logic) ...

Dies wird nach einem add, delete oder merge aufgerufen.

Hinweis

Ab 0.8 wird dieses Ereignis ausgelöst, *nachdem* das Element vollständig der Session zugeordnet wurde, was sich von früheren Versionen unterscheidet. Für Ereignishandler, die erfordern, dass das Objekt noch kein Teil des Session-Zustands ist (z.B. Handler, die möglicherweise autoflush ausführen, während das Zielobjekt noch nicht vollständig ist), sollten Sie das neue Ereignis before_attach() in Betracht ziehen.

method sqlalchemy.orm.SessionEvents.after_begin(session: Session, transaction: SessionTransaction, connection: Connection) None

Wird ausgeführt, nachdem eine Transaktion für eine Verbindung begonnen wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_begin')
def receive_after_begin(session, transaction, connection):
    "listen for the 'after_begin' event"

    # ... (event handling logic) ...

Hinweis

Dieses Ereignis wird während des Prozesses aufgerufen, bei dem die Session ihren internen Zustand ändert. Um SQL-Operationen innerhalb dieses Hooks aufzurufen, verwenden Sie die der Ereignisübergabe bereitgestellte Connection; führen Sie keine SQL-Operationen direkt über die Session aus.

Parameter:
method sqlalchemy.orm.SessionEvents.after_bulk_delete(delete_context: _O) None

Ereignis nach Aufruf der Legacy-Methode Query.delete().

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_bulk_delete')
def receive_after_bulk_delete(delete_context):
    "listen for the 'after_bulk_delete' event"

    # ... (event handling logic) ...

# DEPRECATED calling style (pre-0.9, will be removed in a future release)
@event.listens_for(SomeSessionClassOrObject, 'after_bulk_delete')
def receive_after_bulk_delete(session, query, query_context, result):
    "listen for the 'after_bulk_delete' event"

    # ... (event handling logic) ...

Geändert in Version 0.9: Das Ereignis SessionEvents.after_bulk_delete() akzeptiert nun die Argumente SessionEvents.after_bulk_delete.delete_context. Die Unterstützung für Listener-Funktionen, die die vorherigen Argument-Signaturen (wie oben aufgeführt) als „veraltet“ akzeptieren, wird in einer zukünftigen Version entfernt.

Legacy-Funktion

Die Methode SessionEvents.after_bulk_delete() ist ab SQLAlchemy 2.0 ein Legacy-Ereignishook. Das Ereignis nimmt nicht teil an 2.0-Stil-Aufrufen unter Verwendung von delete(), wie unter ORM UPDATE und DELETE mit benutzerdefinierten WHERE-Kriterien dokumentiert. Für die Verwendung im 2.0-Stil fängt der Hook SessionEvents.do_orm_execute() diese Aufrufe ab.

Parameter:

delete_context

ein „delete context“-Objekt, das Details zur Löschung enthält, einschließlich dieser Attribute

  • session - die beteiligte Session

  • query - das Query-Objekt, auf dem dieser Löschvorgang aufgerufen wurde.

  • result das CursorResult, das als Ergebnis des Bulk-DELETE-Vorgangs zurückgegeben wird.

Geändert in Version 1.4: Der update_context hat kein QueryContext-Objekt mehr, das ihm zugeordnet ist.

method sqlalchemy.orm.SessionEvents.after_bulk_update(update_context: _O) None

Ereignis nach Aufruf der Legacy-Methode Query.update().

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_bulk_update')
def receive_after_bulk_update(update_context):
    "listen for the 'after_bulk_update' event"

    # ... (event handling logic) ...

# DEPRECATED calling style (pre-0.9, will be removed in a future release)
@event.listens_for(SomeSessionClassOrObject, 'after_bulk_update')
def receive_after_bulk_update(session, query, query_context, result):
    "listen for the 'after_bulk_update' event"

    # ... (event handling logic) ...

Geändert in Version 0.9: Das Ereignis SessionEvents.after_bulk_update() akzeptiert nun die Argumente SessionEvents.after_bulk_update.update_context. Die Unterstützung für Listener-Funktionen, die die vorherigen Argument-Signaturen (wie oben aufgeführt) als „veraltet“ akzeptieren, wird in einer zukünftigen Version entfernt.

Legacy-Funktion

Die Methode SessionEvents.after_bulk_update() ist ab SQLAlchemy 2.0 ein Legacy-Ereignishook. Das Ereignis nimmt nicht teil an 2.0-Stil-Aufrufen unter Verwendung von update(), wie unter ORM UPDATE und DELETE mit benutzerdefinierten WHERE-Kriterien dokumentiert. Für die Verwendung im 2.0-Stil fängt der Hook SessionEvents.do_orm_execute() diese Aufrufe ab.

Parameter:

update_context

ein „update context“-Objekt, das Details zur Aktualisierung enthält, einschließlich dieser Attribute

  • session - die beteiligte Session

  • query - das Query-Objekt, auf dem dieser Löschvorgang aufgerufen wurde.

  • values Das „values“-Dictionary, das an Query.update() übergeben wurde.

  • result das CursorResult, das als Ergebnis des Bulk-UPDATE-Vorgangs zurückgegeben wird.

Geändert in Version 1.4: Der update_context hat kein QueryContext-Objekt mehr, das ihm zugeordnet ist.

method sqlalchemy.orm.SessionEvents.after_commit(session: Session) None

Wird ausgeführt, nachdem ein Commit erfolgt ist.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_commit')
def receive_after_commit(session):
    "listen for the 'after_commit' event"

    # ... (event handling logic) ...

Hinweis

Der Hook SessionEvents.after_commit() ist *nicht* pro Flush, d.h. die Session kann innerhalb des Gültigkeitsbereichs einer Transaktion viele Male SQL an die Datenbank emittieren. Für die Abfangung dieser Ereignisse verwenden Sie die Ereignisse SessionEvents.before_flush(), SessionEvents.after_flush() oder SessionEvents.after_flush_postexec().

Hinweis

Die Session befindet sich nicht in einer aktiven Transaktion, wenn das Ereignis SessionEvents.after_commit() aufgerufen wird, und kann daher kein SQL emittieren. Um SQL für jede Transaktion zu emittieren, verwenden Sie das Ereignis SessionEvents.before_commit().

Parameter:

session – Die Ziel-Session.

method sqlalchemy.orm.SessionEvents.after_flush(session: Session, flush_context: UOWTransaction) None

Wird ausgeführt, nachdem der Flush abgeschlossen ist, aber bevor der Commit aufgerufen wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_flush')
def receive_after_flush(session, flush_context):
    "listen for the 'after_flush' event"

    # ... (event handling logic) ...

Beachten Sie, dass sich der Zustand der Session noch im Vor-Flush-Zustand befindet, d.h. die Listen „new“, „dirty“ und „deleted“ zeigen immer noch den Vor-Flush-Zustand sowie die Verlaufs-Einstellungen für Instanzattribute an.

Warnung

Dieses Ereignis wird ausgeführt, nachdem die Session SQL zur Änderung der Datenbank emittiert hat, aber bevor sie ihren internen Zustand geändert hat, um diese Änderungen widerzuspiegeln, einschließlich der Tatsache, dass neu eingefügte Objekte in die Identitätszuordnung aufgenommen werden. ORM-Operationen, die innerhalb dieses Ereignisses emittiert werden, wie z.B. das Laden von zugehörigen Elementen, können neue Identitätszuordnungseinträge erstellen, die sofort ersetzt werden, was manchmal zu verwirrenden Ergebnissen führt. SQLAlchemy gibt ab Version 1.3.9 eine Warnung für diesen Zustand aus.

Parameter:
method sqlalchemy.orm.SessionEvents.after_flush_postexec(session: Session, flush_context: UOWTransaction) None

Wird ausgeführt, nachdem der Flush abgeschlossen ist und nach dem Post-Exec-Zustand.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_flush_postexec')
def receive_after_flush_postexec(session, flush_context):
    "listen for the 'after_flush_postexec' event"

    # ... (event handling logic) ...

Dies ist der Zeitpunkt, an dem die Listen „new“, „dirty“ und „deleted“ ihren endgültigen Zustand erreicht haben. Ein tatsächlicher commit() kann stattgefunden haben oder auch nicht, abhängig davon, ob der Flush seine eigene Transaktion gestartet hat oder an einer größeren Transaktion beteiligt war.

Parameter:
method sqlalchemy.orm.SessionEvents.after_rollback(session: Session) None

Wird ausgeführt, nachdem ein echtes DBAPI-Rollback stattgefunden hat.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_rollback')
def receive_after_rollback(session):
    "listen for the 'after_rollback' event"

    # ... (event handling logic) ...

Beachten Sie, dass dieses Ereignis nur ausgelöst wird, wenn das *tatsächliche* Rollback gegen die Datenbank erfolgt – es wird *nicht* jedes Mal ausgelöst, wenn die Methode Session.rollback() aufgerufen wird, falls die zugrunde liegende DBAPI-Transaktion bereits zurückgerollt wurde. In vielen Fällen befindet sich die Session während dieses Ereignisses nicht in einem „aktiven“ Zustand, da die aktuelle Transaktion ungültig ist. Um eine Session zu erhalten, die nach dem Abschluss des äußersten Rollbacks aktiv ist, verwenden Sie das Ereignis SessionEvents.after_soft_rollback() und überprüfen Sie das Flag Session.is_active.

Parameter:

session – Die Ziel-Session.

Methode sqlalchemy.orm.SessionEvents.after_soft_rollback(session: Session, previous_transaction: SessionTransaction) None

Wird nach jedem Rollback ausgeführt, einschließlich „weicher“ Rollbacks, die auf DBAPI-Ebene keine tatsächliche Aktion auslösen.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_soft_rollback')
def receive_after_soft_rollback(session, previous_transaction):
    "listen for the 'after_soft_rollback' event"

    # ... (event handling logic) ...

Dies betrifft sowohl verschachtelte als auch äußere Rollbacks, d. h. den innersten Rollback, der die rollback()-Methode des DBAPI aufruft, sowie die umschließenden Rollback-Aufrufe, die sich nur selbst aus dem Transaktionsstapel entfernen.

Die angegebene Session kann verwendet werden, um SQL und Session.query()-Operationen nach einem äußersten Rollback aufzurufen, indem zuerst das Session.is_active-Flag geprüft wird.

@event.listens_for(Session, "after_soft_rollback")
def do_something(session, previous_transaction):
    if session.is_active:
        session.execute(text("select * from some_table"))
Parameter:
Methode sqlalchemy.orm.SessionEvents.after_transaction_create(session: Session, transaction: SessionTransaction) None

Wird ausgeführt, wenn eine neue SessionTransaction erstellt wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_transaction_create')
def receive_after_transaction_create(session, transaction):
    "listen for the 'after_transaction_create' event"

    # ... (event handling logic) ...

Dieses Ereignis unterscheidet sich von SessionEvents.after_begin() dadurch, dass es für jede SessionTransaction insgesamt auftritt, im Gegensatz zum Beginn von Transaktionen auf einzelnen Datenbankverbindungen. Es wird auch für verschachtelte Transaktionen und Subtransaktionen aufgerufen und immer von einem entsprechenden SessionEvents.after_transaction_end()-Ereignis begleitet (vorausgesetzt, die normale Funktionsweise der Session).

Parameter:
  • session – die Ziel-Session.

  • transaction

    die Ziel-SessionTransaction.

    Um zu erkennen, ob es sich um die äußerste SessionTransaction handelt, im Gegensatz zu einer „Subtransaktion“ oder einem SAVEPOINT, prüfen Sie, ob das Attribut SessionTransaction.parent None ist.

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

    Um zu erkennen, ob die SessionTransaction ein SAVEPOINT ist, verwenden Sie das Attribut SessionTransaction.nested.

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

Methode sqlalchemy.orm.SessionEvents.after_transaction_end(session: Session, transaction: SessionTransaction) None

Wird ausgeführt, wenn der Gültigkeitsbereich einer SessionTransaction endet.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_transaction_end')
def receive_after_transaction_end(session, transaction):
    "listen for the 'after_transaction_end' event"

    # ... (event handling logic) ...

Dieses Ereignis unterscheidet sich von SessionEvents.after_commit() dadurch, dass es allen verwendeten SessionTransaction-Objekten entspricht, einschließlich derjenigen für verschachtelte Transaktionen und Subtransaktionen. Es wird immer von einem entsprechenden SessionEvents.after_transaction_create()-Ereignis begleitet.

Parameter:
  • session – die Ziel-Session.

  • transaction

    die Ziel-SessionTransaction.

    Um zu erkennen, ob es sich um die äußerste SessionTransaction handelt, im Gegensatz zu einer „Subtransaktion“ oder einem SAVEPOINT, prüfen Sie, ob das Attribut SessionTransaction.parent None ist.

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

    Um zu erkennen, ob die SessionTransaction ein SAVEPOINT ist, verwenden Sie das Attribut SessionTransaction.nested.

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

Methode sqlalchemy.orm.SessionEvents.before_attach(session: Session, instance: _O) None

Wird ausgeführt, bevor eine Instanz an eine Session angehängt wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'before_attach')
def receive_before_attach(session, instance):
    "listen for the 'before_attach' event"

    # ... (event handling logic) ...

Dies wird aufgerufen, bevor ein add, delete oder merge das Objekt zu einem Teil der Session macht.

Methode sqlalchemy.orm.SessionEvents.before_commit(session: Session) None

Wird ausgeführt, bevor commit aufgerufen wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'before_commit')
def receive_before_commit(session):
    "listen for the 'before_commit' event"

    # ... (event handling logic) ...

Hinweis

Der Hook SessionEvents.before_commit() ist nicht pro Flush; das heißt, die Session kann innerhalb des Gültigkeitsbereichs einer Transaktion viele Male SQL an die Datenbank senden. Für die Abfangen dieser Ereignisse verwenden Sie die Ereignisse SessionEvents.before_flush(), SessionEvents.after_flush() oder SessionEvents.after_flush_postexec().

Parameter:

session – Die Ziel-Session.

Methode sqlalchemy.orm.SessionEvents.before_flush(session: Session, flush_context: UOWTransaction, instances: Sequence[_O] | None) None

Wird ausgeführt, bevor der Flush-Prozess begonnen hat.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'before_flush')
def receive_before_flush(session, flush_context, instances):
    "listen for the 'before_flush' event"

    # ... (event handling logic) ...
Parameter:
  • session – Die Ziel-Session.

  • flush_context – Internes UOWTransaction-Objekt, das die Details des Flush-Vorgangs verwaltet.

  • instances – Normalerweise None, dies ist die Sammlung von Objekten, die an die Methode Session.flush() übergeben werden können (beachten Sie, dass diese Verwendung veraltet ist).

Methode sqlalchemy.orm.SessionEvents.deleted_to_detached(session: Session, instance: _O) None

Abfangen des Übergangs von „gelöscht zu getrennt“ für ein bestimmtes Objekt.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'deleted_to_detached')
def receive_deleted_to_detached(session, instance):
    "listen for the 'deleted_to_detached' event"

    # ... (event handling logic) ...

Dieses Ereignis wird aufgerufen, wenn ein gelöschtes Objekt aus der Session entfernt wird. Der typische Fall dafür ist, wenn die Transaktion einer Session, in der das Objekt gelöscht wurde, committet wird; das Objekt wechselt vom Status „gelöscht“ zum Status „getrennt“.

Es wird auch für Objekte aufgerufen, die in einem Flush gelöscht wurden, wenn die Ereignisse Session.expunge_all() oder Session.close() aufgerufen werden, sowie wenn das Objekt individuell aus seinem gelöschten Zustand mittels Session.expunge() entfernt wird.

Methode sqlalchemy.orm.SessionEvents.deleted_to_persistent(session: Session, instance: _O) None

Abfangen des Übergangs von „gelöscht zu persistent“ für ein bestimmtes Objekt.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'deleted_to_persistent')
def receive_deleted_to_persistent(session, instance):
    "listen for the 'deleted_to_persistent' event"

    # ... (event handling logic) ...

Dieser Übergang tritt nur auf, wenn ein Objekt, das in einem Flush erfolgreich gelöscht wurde, aufgrund eines Aufrufs von Session.rollback() wiederhergestellt wird. Das Ereignis wird unter keinen anderen Umständen aufgerufen.

Methode sqlalchemy.orm.SessionEvents.detached_to_persistent(session: Session, instance: _O) None

Abfangen des Übergangs von „getrennt zu persistent“ für ein bestimmtes Objekt.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'detached_to_persistent')
def receive_detached_to_persistent(session, instance):
    "listen for the 'detached_to_persistent' event"

    # ... (event handling logic) ...

Dieses Ereignis ist eine Spezialisierung des Ereignisses SessionEvents.after_attach(), das nur für diesen spezifischen Übergang aufgerufen wird. Es wird typischerweise während des Aufrufs von Session.add() aufgerufen, sowie während des Aufrufs von Session.delete(), wenn das Objekt nicht zuvor mit der Session verbunden war (beachten Sie, dass ein als „gelöscht“ markiertes Objekt bis zum Fortfahren des Flush im Status „persistent“ bleibt).

Hinweis

Wenn das Objekt als Teil eines Aufrufs von Session.delete() persistent wird, ist das Objekt zum Zeitpunkt des Aufrufs dieses Ereignisses noch nicht als gelöscht markiert. Um gelöschte Objekte zu erkennen, prüfen Sie das Flag deleted, das an das Ereignis SessionEvents.persistent_to_detached() gesendet wird, nachdem der Flush fortgefahren ist, oder prüfen Sie die Sammlung Session.deleted innerhalb des Ereignisses SessionEvents.before_flush(), wenn gelöschte Objekte vor dem Flush abgefangen werden müssen.

Parameter:
  • session – Ziel-Session

  • instance – die ORM-geprägte Instanz, auf die die Operation angewendet wird.

Attribut sqlalchemy.orm.SessionEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.SessionEventsDispatch object>

Referenz zurück zur _Dispatch-Klasse.

Bidirektional zu _Dispatch._events

Methode sqlalchemy.orm.SessionEvents.do_orm_execute(orm_execute_state: ORMExecuteState) None

Abfangen von Anweisungs-Ausführungen, die im Auftrag eines ORM Session-Objekts erfolgen.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'do_orm_execute')
def receive_do_orm_execute(orm_execute_state):
    "listen for the 'do_orm_execute' event"

    # ... (event handling logic) ...

Dieses Ereignis wird für alle Top-Level-SQL-Anweisungen aufgerufen, die über die Methode Session.execute() aufgerufen werden, sowie für verwandte Methoden wie Session.scalars() und Session.scalar(). Ab SQLAlchemy 1.4 nehmen alle ORM-Abfragen, die über die Methode Session.execute() sowie verwandte Methoden Session.scalars(), Session.scalar() usw. teil. Dieser Hook gilt nicht für Abfragen, die intern während des ORM-Flush-Prozesses ausgeführt werden, d. h. für den Prozess, der unter Flushing beschrieben wird.

Hinweis

Der Ereignishook SessionEvents.do_orm_execute() wird nur für ORM-Anweisungsausführungen ausgelöst, d. h. für diejenigen, die über die Methode Session.execute() und ähnliche Methoden des Session-Objekts aufgerufen werden. Er wird nicht für Anweisungen ausgelöst, die ausschließlich von SQLAlchemy Core aufgerufen werden, d. h. für Anweisungen, die direkt mit Connection.execute() aufgerufen werden oder anderweitig von einem Engine-Objekt stammen, ohne dass eine Session beteiligt ist. Um alle SQL-Ausführungen abzufangen, unabhängig davon, ob die Core- oder ORM-APIs verwendet werden, siehe die Ereignishooks in ConnectionEvents, wie z. B. ConnectionEvents.before_execute() und ConnectionEvents.before_cursor_execute().

Außerdem gilt dieser Hook nicht für Abfragen, die intern während des ORM-Flush-Prozesses ausgeführt werden, d. h. für den Prozess, der unter Flushing beschrieben wird; um Schritte innerhalb des Flush-Prozesses abzufangen, siehe die Ereignishooks, die unter Persistence Events sowie Mapper-level Flush Events beschrieben sind.

Dieses Ereignis ist ein do_-Ereignis, was bedeutet, dass es die Möglichkeit hat, die Operation zu ersetzen, die die Methode Session.execute() normalerweise ausführt. Der beabsichtigte Verwendungszweck umfasst Sharding- und Result-Caching-Schemata, die möglicherweise dieselbe Anweisung über mehrere Datenbankverbindungen ausführen, ein Ergebnis zurückgeben, das von jeder einzelnen zusammengeführt wird, oder die Anweisung gar nicht ausführen und stattdessen Daten aus einem Cache zurückgeben.

Der Hook soll die Verwendung der Methode Query._execute_and_instances ersetzen, die vor SQLAlchemy 1.4 unterklassifiziert werden konnte.

Parameter:

orm_execute_state – eine Instanz von ORMExecuteState, die alle Informationen über die aktuelle Ausführung enthält, sowie Hilfsfunktionen, die zur Ableitung anderer häufig benötigter Informationen verwendet werden. Siehe dieses Objekt für Details.

Siehe auch

Execute Events - Top-Level-Dokumentation zur Verwendung von SessionEvents.do_orm_execute()

ORMExecuteState - Das Objekt, das an das Ereignis SessionEvents.do_orm_execute() übergeben wird, das alle Informationen über die auszuführende Anweisung enthält. Es stellt auch eine Schnittstelle zur Erweiterung der aktuellen Anweisung, Optionen und Parameter sowie eine Option zur programmatischen Ausführung der Anweisung zu jedem Zeitpunkt bereit.

ORM Query Events - Enthält Beispiele für die Verwendung von SessionEvents.do_orm_execute()

Dogpile Caching - Ein Beispiel für die Integration von Dogpile-Caching mit dem ORM Session unter Verwendung des Ereignishooks SessionEvents.do_orm_execute().

Horizontal Sharding - Das Beispiel / die Erweiterung für horizontales Sharding basiert auf dem Ereignishook SessionEvents.do_orm_execute(), um eine SQL-Anweisung auf mehreren Backends auszuführen und ein zusammengeführtes Ergebnis zurückzugeben.

Neu in Version 1.4.

method sqlalchemy.orm.SessionEvents.loaded_as_persistent(session: Session, instance: _O) None

Fängt den Übergang „geladen als persistent“ für ein bestimmtes Objekt ab.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'loaded_as_persistent')
def receive_loaded_as_persistent(session, instance):
    "listen for the 'loaded_as_persistent' event"

    # ... (event handling logic) ...

Dieses Ereignis wird während des ORM-Ladevorgangs aufgerufen und ähnelt stark dem Ereignis InstanceEvents.load(). Das Ereignis ist jedoch mit einer Session-Klasse oder -Instanz verknüpfbar, anstatt mit einer Mapper- oder Klassenhierarchie, und integriert sich nahtlos in die anderen Sitzungslebenszyklusereignisse. Das Objekt ist garantiert in der Identitätszuordnung der Sitzung vorhanden, wenn dieses Ereignis aufgerufen wird.

Hinweis

Dieses Ereignis wird während des Ladevorgangs aufgerufen, bevor Eager-Loader möglicherweise abgeschlossen sind, und der Zustand des Objekts ist möglicherweise noch nicht vollständig. Darüber hinaus führen Aufrufe von Zeilenaktualisierungsoperationen für das Objekt zu einem neuen Ladekontext, was den bestehenden Ladekontext stört. Siehe die Notiz zu InstanceEvents.load() für Hintergrundinformationen zur Verwendung des Parameters SessionEvents.restore_load_context, der auf die gleiche Weise wie bei InstanceEvents.restore_load_context funktioniert, um dieses Szenario zu lösen.

Parameter:
  • session – Ziel-Session

  • instance – die ORM-gemappte Instanz, die gerade bearbeitet wird.

method sqlalchemy.orm.SessionEvents.pending_to_persistent(session: Session, instance: _O) None

Fängt den Übergang „pending zu persistent“ für ein bestimmtes Objekt ab.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'pending_to_persistent')
def receive_pending_to_persistent(session, instance):
    "listen for the 'pending_to_persistent' event"

    # ... (event handling logic) ...

Dieses Ereignis wird während des Flush-Prozesses aufgerufen und ähnelt dem Durchsuchen der Sammlung Session.new im Ereignis SessionEvents.after_flush(). In diesem Fall wurde das Objekt jedoch bereits in den persistenten Zustand verschoben, wenn das Ereignis aufgerufen wird.

Parameter:
  • session – Ziel-Session

  • instance – die ORM-gemappte Instanz, die gerade bearbeitet wird.

method sqlalchemy.orm.SessionEvents.pending_to_transient(session: Session, instance: _O) None

Fängt den Übergang „pending zu transient“ für ein bestimmtes Objekt ab.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'pending_to_transient')
def receive_pending_to_transient(session, instance):
    "listen for the 'pending_to_transient' event"

    # ... (event handling logic) ...

Dieser weniger häufige Übergang tritt auf, wenn ein ausstehendes Objekt, das noch nicht geflusht wurde, aus der Sitzung entfernt wird; dies kann passieren, wenn die Methode Session.rollback() die Transaktion zurückrollt oder wenn die Methode Session.expunge() verwendet wird.

Parameter:
  • session – Ziel-Session

  • instance – die ORM-gemappte Instanz, die gerade bearbeitet wird.

method sqlalchemy.orm.SessionEvents.persistent_to_deleted(session: Session, instance: _O) None

Fängt den Übergang „persistent zu gelöscht“ für ein bestimmtes Objekt ab.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'persistent_to_deleted')
def receive_persistent_to_deleted(session, instance):
    "listen for the 'persistent_to_deleted' event"

    # ... (event handling logic) ...

Dieses Ereignis wird aufgerufen, wenn die Identität eines persistenten Objekts während eines Flushs aus der Datenbank gelöscht wird. Das Objekt bleibt jedoch bis zum Abschluss der Transaktion mit der Session assoziiert.

Wenn die Transaktion zurückgerollt wird, wechselt das Objekt erneut in den persistenten Zustand, und das Ereignis SessionEvents.deleted_to_persistent() wird aufgerufen. Wenn die Transaktion committet wird, wird das Objekt getrennt, was das Ereignis SessionEvents.deleted_to_detached() auslöst.

Beachten Sie, dass die Methode Session.delete() zwar die primäre öffentliche Schnittstelle ist, um ein Objekt als gelöscht zu markieren, viele Objekte jedoch aufgrund von Kaskadierungsregeln gelöscht werden, die erst zur Flush-Zeit bestimmt werden. Daher gibt es keine Möglichkeit, jedes gelöschte Objekt zu erfassen, bis der Flush fortgeschritten ist. Das Ereignis SessionEvents.persistent_to_deleted() wird daher am Ende eines Flush aufgerufen.

method sqlalchemy.orm.SessionEvents.persistent_to_detached(session: Session, instance: _O) None

Fängt den Übergang „persistent zu detached“ für ein bestimmtes Objekt ab.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'persistent_to_detached')
def receive_persistent_to_detached(session, instance):
    "listen for the 'persistent_to_detached' event"

    # ... (event handling logic) ...

Dieses Ereignis wird aufgerufen, wenn ein persistentes Objekt aus der Sitzung entfernt wird. Es gibt viele Bedingungen, die dazu führen, darunter:

Parameter:
  • session – Ziel-Session

  • instance – die ORM-gemappte Instanz, die gerade bearbeitet wird.

  • deleted – boolesch. Wenn True, zeigt dies an, dass das Objekt in den detached-Zustand übergegangen ist, weil es als gelöscht markiert und geflusht wurde.

method sqlalchemy.orm.SessionEvents.persistent_to_transient(session: Session, instance: _O) None

Fängt den Übergang „persistent zu transient“ für ein bestimmtes Objekt ab.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'persistent_to_transient')
def receive_persistent_to_transient(session, instance):
    "listen for the 'persistent_to_transient' event"

    # ... (event handling logic) ...

Dieser weniger häufige Übergang tritt auf, wenn ein ausstehendes Objekt, das geflusht wurde, aus der Sitzung entfernt wird. Dies kann passieren, wenn die Methode Session.rollback() die Transaktion zurückrollt.

Parameter:
  • session – Ziel-Session

  • instance – die ORM-gemappte Instanz, die gerade bearbeitet wird.

method sqlalchemy.orm.SessionEvents.transient_to_pending(session: Session, instance: _O) None

Fängt den Übergang „transient zu pending“ für ein bestimmtes Objekt ab.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'transient_to_pending')
def receive_transient_to_pending(session, instance):
    "listen for the 'transient_to_pending' event"

    # ... (event handling logic) ...

Dieses Ereignis ist eine Spezialisierung des Ereignisses SessionEvents.after_attach(), das nur für diesen spezifischen Übergang aufgerufen wird. Es wird typischerweise während des Aufrufs von Session.add() aufgerufen.

Parameter:
  • session – Ziel-Session

  • instance – die ORM-gemappte Instanz, die gerade bearbeitet wird.

Mapper Events

Mapper-Ereignishooks umfassen Dinge, die im Zusammenhang mit einzelnen oder mehreren Mapper-Objekten geschehen, die das zentrale Konfigurationsobjekt sind, das eine benutzerdefinierte Klasse einer Table-Objekt zuordnet. Zu den Arten von Dingen, die auf Mapper-Ebene auftreten, gehören:

Objektname Beschreibung

MapperEvents

Definiert ereignisspezifische Zuordnungen.

class sqlalchemy.orm.MapperEvents

Definiert ereignisspezifische Zuordnungen.

z. B.

from sqlalchemy import event


def my_before_insert_listener(mapper, connection, target):
    # execute a stored procedure upon INSERT,
    # apply the value to the row to be inserted
    target.calculated_value = connection.execute(
        text("select my_special_function(%d)" % target.special_number)
    ).scalar()


# associate the listener function with SomeClass,
# to execute during the "before_insert" hook
event.listen(SomeClass, "before_insert", my_before_insert_listener)

Verfügbare Ziele umfassen

  • zugeordnete Klassen

  • nicht zugeordnete Oberklassen von zugeordneten oder noch zuzuordnenden Klassen (mit dem Flag propagate=True)

  • Mapper-Objekte

  • die Mapper-Klasse selbst gibt an, dass für alle Mapper zugehört wird.

Mapper-Ereignisse bieten Hooks in kritischen Abschnitten des Mappers, einschließlich solcher, die sich auf die Objektinstrumentierung, das Laden von Objekten und die Objektpersistenz beziehen. Insbesondere sind die Persistenzmethoden MapperEvents.before_insert() und MapperEvents.before_update() beliebte Orte, um den zu persistenten Zustand zu erweitern. Diese Methoden haben jedoch mehrere signifikante Einschränkungen. Der Benutzer wird ermutigt, die Methoden SessionEvents.before_flush() und SessionEvents.after_flush() als flexiblere und benutzerfreundlichere Hooks zu bewerten, um zusätzliche Datenbankzustände während eines Flushs anzuwenden.

Bei der Verwendung von MapperEvents sind mehrere Modifikatoren für die Funktion listen() verfügbar.

Parameter:
  • propagate=False – Wenn True, sollte der Ereignis-Listener auf alle erbenden Mapper und/oder die Mapper von erbenden Klassen sowie auf jeden Mapper angewendet werden, der das Ziel dieses Listeners ist.

  • raw=False – Wenn True, ist das an die entsprechenden Ereignis-Listener-Funktionen übergebene „target“-Argument das InstanceState-Verwaltungsobjekt der Instanz und nicht die zugeordnete Instanz selbst.

  • retval=False

    wenn True, muss die benutzerdefinierte Ereignisfunktion einen Rückgabewert haben, dessen Zweck entweder die Steuerung der nachfolgenden Ereignisweitergabe ist oder die laufende Operation des Mappers anderweitig zu ändern. Mögliche Rückgabewerte sind:

    • sqlalchemy.orm.interfaces.EXT_CONTINUE - Die Ereignisverarbeitung normal fortsetzen.

    • sqlalchemy.orm.interfaces.EXT_STOP - Alle nachfolgenden Ereignis-Handler in der Kette abbrechen.

    • andere Werte – der von spezifischen Listenern angegebene Rückgabewert.

Klassensignatur

class sqlalchemy.orm.MapperEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.MapperEvents.after_configured() None

Aufgerufen nach der Konfiguration einer Reihe von Mappern.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_configured')
def receive_after_configured():
    "listen for the 'after_configured' event"

    # ... (event handling logic) ...

Das Ereignis MapperEvents.after_configured() wird jedes Mal aufgerufen, wenn die Funktion configure_mappers() aufgerufen wird, nachdem die Funktion ihre Arbeit abgeschlossen hat. configure_mappers() wird typischerweise automatisch aufgerufen, wenn Zuordnungen erstmals verwendet werden, sowie jedes Mal, wenn neue Mapper verfügbar gemacht wurden und eine neue Mapper-Nutzung erkannt wird.

Vergleichen Sie dieses Ereignis mit dem Ereignis MapperEvents.mapper_configured(), das pro Mapper aufgerufen wird, während der Konfigurationsvorgang fortschreitet; im Gegensatz zu diesem Ereignis sind, wenn dieses Ereignis aufgerufen wird, alle Querkonfigurationen (z. B. Backrefs) auch für alle wartenden Mapper verfügbar. Vergleichen Sie auch mit MapperEvents.before_configured(), das aufgerufen wird, bevor die Reihe von Mappern konfiguriert wurde.

Dieses Ereignis kann **nur** auf die Mapper-Klasse und nicht auf einzelne Zuordnungen oder zugeordnete Klassen angewendet werden. Es wird nur für alle Zuordnungen als Ganzes aufgerufen.

from sqlalchemy.orm import Mapper


@event.listens_for(Mapper, "after_configured")
def go(): ...

Theoretisch wird dieses Ereignis einmal pro Anwendung aufgerufen, aber tatsächlich wird es jedes Mal aufgerufen, wenn neue Mapper von einem Aufruf von configure_mappers() betroffen sind. Wenn neue Zuordnungen nach der Verwendung bestehender Zuordnungen erstellt werden, wird dieses Ereignis wahrscheinlich erneut aufgerufen. Um sicherzustellen, dass ein bestimmtes Ereignis nur einmal und nicht weiter aufgerufen wird, kann das Argument once=True (neu ab 0.9.4) angewendet werden.

from sqlalchemy.orm import mapper


@event.listens_for(mapper, "after_configured", once=True)
def go(): ...
method sqlalchemy.orm.MapperEvents.after_delete(mapper: Mapper[_O], connection: Connection, target: _O) None

Erhält eine Objektinstanz, nachdem eine DELETE-Anweisung, die dieser Instanz entspricht, ausgegeben wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_delete')
def receive_after_delete(mapper, connection, target):
    "listen for the 'after_delete' event"

    # ... (event handling logic) ...

Hinweis

Dieses Ereignis gilt **nur** für die Sitzungs-Flush-Operation und gilt **nicht** für die ORM DML-Operationen, die unter ORM-aktivierte INSERT-, UPDATE- und DELETE-Anweisungen beschrieben sind. Um ORM DML-Ereignisse abzufangen, verwenden Sie SessionEvents.do_orm_execute().

Dieses Ereignis wird verwendet, um zusätzliche SQL-Anweisungen auf der angegebenen Verbindung auszugeben sowie anwendungsspezifische Buchhaltung für ein Löschereignis durchzuführen.

Das Ereignis wird oft für eine Gruppe von Objekten derselben Klasse aufgerufen, nachdem deren DELETE-Anweisungen in einem früheren Schritt auf einmal ausgegeben wurden.

Warnung

Mapper-Flush-Ereignisse erlauben **nur sehr begrenzte Operationen** auf Attributen, die lokal zur gerade bearbeiteten Zeile sind, sowie das Ausgeben von SQL auf der gegebenen Connection. **Bitte lesen Sie vollständig** die Hinweise unter Mapper-Level Flush Events für Richtlinien zur Verwendung dieser Methoden; im Allgemeinen sollte die Methode SessionEvents.before_flush() für allgemeine Änderungen während des Flush bevorzugt werden.

Parameter:
  • mapper – der Mapper, der das Ziel dieses Ereignisses ist.

  • connection – die Connection, die zum Ausgeben von DELETE-Anweisungen für diese Instanz verwendet wird. Dies bietet einen Zugriff auf die aktuelle Transaktion auf der Zieldatenbank, die spezifisch für diese Instanz ist.

  • target – die zugeordnete Instanz, die gelöscht wird. Wenn das Ereignis mit raw=True konfiguriert wurde, ist dies stattdessen das InstanceState-Zustandsverwaltungsobjekt, das mit der Instanz assoziiert ist.

Gibt zurück:

Kein Rückgabewert wird von diesem Ereignis unterstützt.

methode sqlalchemy.orm.MapperEvents.after_insert(mapper: Mapper[_O], connection: Connection, target: _O) None

Empfängt eine Objektinstanz, nachdem eine INSERT-Anweisung für diese Instanz ausgegeben wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_insert')
def receive_after_insert(mapper, connection, target):
    "listen for the 'after_insert' event"

    # ... (event handling logic) ...

Hinweis

Dieses Ereignis gilt **nur** für die Sitzungs-Flush-Operation und gilt **nicht** für die ORM DML-Operationen, die unter ORM-aktivierte INSERT-, UPDATE- und DELETE-Anweisungen beschrieben sind. Um ORM DML-Ereignisse abzufangen, verwenden Sie SessionEvents.do_orm_execute().

Dieses Ereignis wird verwendet, um den reinen Python-Zustand der Instanz nach einem INSERT zu ändern und zusätzliche SQL-Anweisungen über die gegebene Verbindung auszugeben.

Das Ereignis wird oft für eine Gruppe von Objekten derselben Klasse aufgerufen, nachdem deren INSERT-Anweisungen in einem vorherigen Schritt auf einmal ausgegeben wurden. In dem extrem seltenen Fall, dass dies nicht erwünscht ist, kann das Mapper-Objekt mit batch=False konfiguriert werden, wodurch Instanzgruppen in einzelne (und schlechter performende) Ereignis->persist->Ereignisschritte aufgeteilt werden.

Warnung

Mapper-Flush-Ereignisse erlauben **nur sehr begrenzte Operationen** auf Attributen, die lokal zur gerade bearbeiteten Zeile sind, sowie das Ausgeben von SQL auf der gegebenen Connection. **Bitte lesen Sie vollständig** die Hinweise unter Mapper-Level Flush Events für Richtlinien zur Verwendung dieser Methoden; im Allgemeinen sollte die Methode SessionEvents.before_flush() für allgemeine Änderungen während des Flush bevorzugt werden.

Parameter:
  • mapper – Der Mapper, der das Ziel dieses Ereignisses ist.

  • connection – Die Connection, die zum Ausgeben von INSERT-Anweisungen für diese Instanz verwendet wird. Dies bietet einen Zugriff auf die aktuelle Transaktion in der Zieldatenbank, die spezifisch für diese Instanz ist.

  • target – Die zu persistierende gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das InstanceState-Objekt zur Zustandsverwaltung, das mit der Instanz verbunden ist.

Gibt zurück:

Kein Rückgabewert wird von diesem Ereignis unterstützt.

methode sqlalchemy.orm.MapperEvents.after_mapper_constructed(mapper: Mapper[_O], class_: Type[_O]) None

Empfängt eine Klasse und einen Mapper, wenn der Mapper vollständig konstruiert wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_mapper_constructed')
def receive_after_mapper_constructed(mapper, class_):
    "listen for the 'after_mapper_constructed' event"

    # ... (event handling logic) ...

Dieses Ereignis wird nach Abschluss des anfänglichen Konstruktors für Mapper aufgerufen. Dies geschieht nach dem MapperEvents.instrument_class()-Ereignis und nachdem der Mapper einen ersten Durchlauf seiner Argumente durchgeführt hat, um seine Sammlung von MapperProperty-Objekten zu generieren, die über die Methode Mapper.get_property() und das Attribut Mapper.iterate_properties zugänglich sind.

Dieses Ereignis unterscheidet sich vom MapperEvents.before_mapper_configured()-Ereignis dadurch, dass es innerhalb des Konstruktors für Mapper aufgerufen wird, anstatt innerhalb des registry.configure()-Prozesses. Derzeit ist dieses Ereignis das einzige, das für Handler geeignet ist, die als Reaktion auf die Konstruktion dieses Mapper zusätzliche gemappte Klassen erstellen möchten, die Teil desselben Konfigurationsschritts sein werden, wenn registry.configure() erneut ausgeführt wird.

Neu in Version 2.0.2.

Siehe auch

Versioning von Objekten - Ein Beispiel, das die Verwendung des MapperEvents.before_mapper_configured()-Ereignisses veranschaulicht, um neue Mapper zu erstellen, die Änderungsprotokolle für Objekte aufzeichnen.

methode sqlalchemy.orm.MapperEvents.after_update(mapper: Mapper[_O], connection: Connection, target: _O) None

Empfängt eine Objektinstanz, nachdem eine UPDATE-Anweisung für diese Instanz ausgegeben wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_update')
def receive_after_update(mapper, connection, target):
    "listen for the 'after_update' event"

    # ... (event handling logic) ...

Hinweis

Dieses Ereignis gilt **nur** für die Sitzungs-Flush-Operation und gilt **nicht** für die ORM DML-Operationen, die unter ORM-aktivierte INSERT-, UPDATE- und DELETE-Anweisungen beschrieben sind. Um ORM DML-Ereignisse abzufangen, verwenden Sie SessionEvents.do_orm_execute().

Dieses Ereignis wird verwendet, um den reinen Python-Zustand der Instanz nach einem UPDATE zu ändern und zusätzliche SQL-Anweisungen über die gegebene Verbindung auszugeben.

Diese Methode wird für alle Instanzen aufgerufen, die als "dirty" markiert sind, *auch solche, die keine Nettoänderungen an ihren spaltenbasierten Attributen aufweisen*, und für die keine UPDATE-Anweisung durchgeführt wurde. Ein Objekt wird als "dirty" markiert, wenn eine "set attribute"-Operation für eines seiner spaltenbasierten Attribute aufgerufen wird oder wenn eine seiner Sammlungen geändert wird. Wenn zum Zeitpunkt des Updates keine spaltenbasierten Attribute Nettoänderungen aufweisen, wird keine UPDATE-Anweisung ausgegeben. Das bedeutet, dass eine Instanz, die an MapperEvents.after_update() übergeben wird, *keine* Garantie dafür ist, dass eine UPDATE-Anweisung ausgegeben wurde.

Um zu erkennen, ob die spaltenbasierten Attribute des Objekts Nettoänderungen aufweisen und somit eine UPDATE-Anweisung generiert haben, verwenden Sie object_session(instance).is_modified(instance, include_collections=False).

Das Ereignis wird oft für eine Gruppe von Objekten derselben Klasse aufgerufen, nachdem deren UPDATE-Anweisungen in einem vorherigen Schritt auf einmal ausgegeben wurden. In dem extrem seltenen Fall, dass dies nicht erwünscht ist, kann der Mapper mit batch=False konfiguriert werden, wodurch Instanzgruppen in einzelne (und schlechter performende) Ereignis->persist->Ereignisschritte aufgeteilt werden.

Warnung

Mapper-Flush-Ereignisse erlauben **nur sehr begrenzte Operationen** auf Attributen, die lokal zur gerade bearbeiteten Zeile sind, sowie das Ausgeben von SQL auf der gegebenen Connection. **Bitte lesen Sie vollständig** die Hinweise unter Mapper-Level Flush Events für Richtlinien zur Verwendung dieser Methoden; im Allgemeinen sollte die Methode SessionEvents.before_flush() für allgemeine Änderungen während des Flush bevorzugt werden.

Parameter:
  • mapper – Der Mapper, der das Ziel dieses Ereignisses ist.

  • connection – Die Connection, die zum Ausgeben von UPDATE-Anweisungen für diese Instanz verwendet wird. Dies bietet einen Zugriff auf die aktuelle Transaktion in der Zieldatenbank, die spezifisch für diese Instanz ist.

  • target – Die zu persistierende gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das InstanceState-Objekt zur Zustandsverwaltung, das mit der Instanz verbunden ist.

Gibt zurück:

Kein Rückgabewert wird von diesem Ereignis unterstützt.

methode sqlalchemy.orm.MapperEvents.before_configured() None

Wird aufgerufen, bevor eine Reihe von Mappern konfiguriert wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_configured')
def receive_before_configured():
    "listen for the 'before_configured' event"

    # ... (event handling logic) ...

Das MapperEvents.before_configured()-Ereignis wird jedes Mal aufgerufen, wenn die Funktion configure_mappers() aufgerufen wird, bevor die Funktion ihre Arbeit aufgenommen hat. configure_mappers() wird typischerweise automatisch aufgerufen, wenn Mappings zum ersten Mal verwendet werden, sowie jedes Mal, wenn neue Mapper verfügbar gemacht wurden und neue Mapper-Verwendung erkannt wird.

Dieses Ereignis kann **nur** auf die Mapper-Klasse und nicht auf einzelne Zuordnungen oder zugeordnete Klassen angewendet werden. Es wird nur für alle Zuordnungen als Ganzes aufgerufen.

from sqlalchemy.orm import Mapper


@event.listens_for(Mapper, "before_configured")
def go(): ...

Vergleichen Sie dieses Ereignis mit MapperEvents.after_configured(), das nach der Konfiguration der Mapper-Reihe aufgerufen wird, sowie mit MapperEvents.before_mapper_configured() und MapperEvents.mapper_configured(), die beide auf Mapper-Basis aufgerufen werden.

Theoretisch wird dieses Ereignis einmal pro Anwendung aufgerufen, aber tatsächlich wird es jedes Mal aufgerufen, wenn neue Mapper von einem configure_mappers()-Aufruf betroffen sein sollen. Wenn neue Mappings nach bereits verwendeten konstruiert werden, wird dieses Ereignis wahrscheinlich erneut aufgerufen. Um sicherzustellen, dass ein bestimmtes Ereignis nur einmal und nicht weiter aufgerufen wird, kann das Argument once=True (neu ab 0.9.4) verwendet werden.

from sqlalchemy.orm import mapper


@event.listens_for(mapper, "before_configured", once=True)
def go(): ...
methode sqlalchemy.orm.MapperEvents.before_delete(mapper: Mapper[_O], connection: Connection, target: _O) None

Empfängt eine Objektinstanz, bevor eine DELETE-Anweisung für diese Instanz ausgegeben wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_delete')
def receive_before_delete(mapper, connection, target):
    "listen for the 'before_delete' event"

    # ... (event handling logic) ...

Hinweis

Dieses Ereignis gilt **nur** für die Sitzungs-Flush-Operation und gilt **nicht** für die ORM DML-Operationen, die unter ORM-aktivierte INSERT-, UPDATE- und DELETE-Anweisungen beschrieben sind. Um ORM DML-Ereignisse abzufangen, verwenden Sie SessionEvents.do_orm_execute().

Dieses Ereignis wird verwendet, um zusätzliche SQL-Anweisungen auf der angegebenen Verbindung auszugeben sowie anwendungsspezifische Buchhaltung für ein Löschereignis durchzuführen.

Das Ereignis wird oft für eine Gruppe von Objekten derselben Klasse aufgerufen, bevor deren DELETE-Anweisungen in einem späteren Schritt auf einmal ausgegeben werden.

Warnung

Mapper-Flush-Ereignisse erlauben **nur sehr begrenzte Operationen** auf Attributen, die lokal zur gerade bearbeiteten Zeile sind, sowie das Ausgeben von SQL auf der gegebenen Connection. **Bitte lesen Sie vollständig** die Hinweise unter Mapper-Level Flush Events für Richtlinien zur Verwendung dieser Methoden; im Allgemeinen sollte die Methode SessionEvents.before_flush() für allgemeine Änderungen während des Flush bevorzugt werden.

Parameter:
  • mapper – Der Mapper, der das Ziel dieses Ereignisses ist.

  • connection – Die Connection, die zum Ausgeben von DELETE-Anweisungen für diese Instanz verwendet wird. Dies bietet einen Zugriff auf die aktuelle Transaktion in der Zieldatenbank, die spezifisch für diese Instanz ist.

  • target – Die zu löschende gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das InstanceState-Objekt zur Zustandsverwaltung, das mit der Instanz verbunden ist.

Gibt zurück:

Kein Rückgabewert wird von diesem Ereignis unterstützt.

methode sqlalchemy.orm.MapperEvents.before_insert(mapper: Mapper[_O], connection: Connection, target: _O) None

Empfängt eine Objektinstanz, bevor eine INSERT-Anweisung für diese Instanz ausgegeben wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_insert')
def receive_before_insert(mapper, connection, target):
    "listen for the 'before_insert' event"

    # ... (event handling logic) ...

Hinweis

Dieses Ereignis gilt **nur** für die Sitzungs-Flush-Operation und gilt **nicht** für die ORM DML-Operationen, die unter ORM-aktivierte INSERT-, UPDATE- und DELETE-Anweisungen beschrieben sind. Um ORM DML-Ereignisse abzufangen, verwenden Sie SessionEvents.do_orm_execute().

Dieses Ereignis wird verwendet, um lokale, nicht objektbezogene Attribute der Instanz vor einem INSERT zu ändern und zusätzliche SQL-Anweisungen über die gegebene Verbindung auszugeben.

Das Ereignis wird oft für eine Gruppe von Objekten derselben Klasse aufgerufen, bevor deren INSERT-Anweisungen in einem späteren Schritt auf einmal ausgegeben werden. In dem extrem seltenen Fall, dass dies nicht erwünscht ist, kann das Mapper-Objekt mit batch=False konfiguriert werden, wodurch Instanzgruppen in einzelne (und schlechter performende) Ereignis->persist->Ereignisschritte aufgeteilt werden.

Warnung

Mapper-Flush-Ereignisse erlauben **nur sehr begrenzte Operationen** auf Attributen, die lokal zur gerade bearbeiteten Zeile sind, sowie das Ausgeben von SQL auf der gegebenen Connection. **Bitte lesen Sie vollständig** die Hinweise unter Mapper-Level Flush Events für Richtlinien zur Verwendung dieser Methoden; im Allgemeinen sollte die Methode SessionEvents.before_flush() für allgemeine Änderungen während des Flush bevorzugt werden.

Parameter:
  • mapper – Der Mapper, der das Ziel dieses Ereignisses ist.

  • connection – Die Connection, die zum Ausgeben von INSERT-Anweisungen für diese Instanz verwendet wird. Dies bietet einen Zugriff auf die aktuelle Transaktion in der Zieldatenbank, die spezifisch für diese Instanz ist.

  • target – Die zu persistierende gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das InstanceState-Objekt zur Zustandsverwaltung, das mit der Instanz verbunden ist.

Gibt zurück:

Kein Rückgabewert wird von diesem Ereignis unterstützt.

methode sqlalchemy.orm.MapperEvents.before_mapper_configured(mapper: Mapper[_O], class_: Type[_O]) None

Wird kurz vor der Konfiguration eines bestimmten Mappers aufgerufen.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_mapper_configured')
def receive_before_mapper_configured(mapper, class_):
    "listen for the 'before_mapper_configured' event"

    # ... (event handling logic) ...

Dieses Ereignis ist dazu bestimmt, die Überspringung eines bestimmten Mappers während des Konfigurationsschritts zu ermöglichen, indem das Symbol interfaces.EXT_SKIP zurückgegeben wird, das dem configure_mappers()-Aufruf anzeigt, dass dieser bestimmte Mapper (oder eine Hierarchie von Mappern, wenn propagate=True verwendet wird) im aktuellen Konfigurationslauf übersprungen werden soll. Wenn ein oder mehrere Mapper übersprungen werden, bleibt das Flag "neue Mapper" gesetzt, was bedeutet, dass die Funktion configure_mappers() weiterhin aufgerufen wird, wenn Mapper verwendet werden, um zu versuchen, alle verfügbaren Mapper zu konfigurieren.

Im Vergleich zu den anderen Konfigurationsereignissen, MapperEvents.before_configured(), MapperEvents.after_configured() und MapperEvents.mapper_configured(), bietet das MapperEvents.before_mapper_configured()-Ereignis einen aussagekräftigen Rückgabewert, wenn es mit dem Parameter retval=True registriert wird.

Neu in Version 1.3.

z. B.

from sqlalchemy.orm import EXT_SKIP

Base = declarative_base()

DontConfigureBase = declarative_base()


@event.listens_for(
    DontConfigureBase,
    "before_mapper_configured",
    retval=True,
    propagate=True,
)
def dont_configure(mapper, cls):
    return EXT_SKIP
methode sqlalchemy.orm.MapperEvents.before_update(mapper: Mapper[_O], connection: Connection, target: _O) None

Empfängt eine Objektinstanz, bevor eine UPDATE-Anweisung für diese Instanz ausgegeben wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_update')
def receive_before_update(mapper, connection, target):
    "listen for the 'before_update' event"

    # ... (event handling logic) ...

Hinweis

Dieses Ereignis gilt **nur** für die Sitzungs-Flush-Operation und gilt **nicht** für die ORM DML-Operationen, die unter ORM-aktivierte INSERT-, UPDATE- und DELETE-Anweisungen beschrieben sind. Um ORM DML-Ereignisse abzufangen, verwenden Sie SessionEvents.do_orm_execute().

Dieses Ereignis wird verwendet, um lokale, nicht objektbezogene Attribute der Instanz vor einem UPDATE zu ändern und zusätzliche SQL-Anweisungen über die gegebene Verbindung auszugeben.

Diese Methode wird für alle Instanzen aufgerufen, die als "dirty" markiert sind, *auch solche, die keine Nettoänderungen an ihren spaltenbasierten Attributen aufweisen*. Ein Objekt wird als "dirty" markiert, wenn eine "set attribute"-Operation für eines seiner spaltenbasierten Attribute aufgerufen wird oder wenn eine seiner Sammlungen geändert wird. Wenn zum Zeitpunkt des Updates keine spaltenbasierten Attribute Nettoänderungen aufweisen, wird keine UPDATE-Anweisung ausgegeben. Das bedeutet, dass eine Instanz, die an MapperEvents.before_update() übergeben wird, *keine* Garantie dafür ist, dass eine UPDATE-Anweisung ausgegeben wird, obwohl Sie hier den Ausgang beeinflussen können, indem Sie Attribute ändern, sodass eine Nettoänderung des Werts vorhanden ist.

Um zu erkennen, ob die spaltenbasierten Attribute des Objekts Nettoänderungen aufweisen und somit eine UPDATE-Anweisung generieren werden, verwenden Sie object_session(instance).is_modified(instance, include_collections=False).

Das Ereignis wird oft für eine Gruppe von Objekten derselben Klasse aufgerufen, bevor deren UPDATE-Anweisungen in einem späteren Schritt auf einmal ausgegeben werden. In dem extrem seltenen Fall, dass dies nicht erwünscht ist, kann der Mapper mit batch=False konfiguriert werden, wodurch Instanzgruppen in einzelne (und schlechter performende) Ereignis->persist->Ereignisschritte aufgeteilt werden.

Warnung

Mapper-Flush-Ereignisse erlauben **nur sehr begrenzte Operationen** auf Attributen, die lokal zur gerade bearbeiteten Zeile sind, sowie das Ausgeben von SQL auf der gegebenen Connection. **Bitte lesen Sie vollständig** die Hinweise unter Mapper-Level Flush Events für Richtlinien zur Verwendung dieser Methoden; im Allgemeinen sollte die Methode SessionEvents.before_flush() für allgemeine Änderungen während des Flush bevorzugt werden.

Parameter:
  • mapper – Der Mapper, der das Ziel dieses Ereignisses ist.

  • connection – Die Connection, die zum Ausgeben von UPDATE-Anweisungen für diese Instanz verwendet wird. Dies bietet einen Zugriff auf die aktuelle Transaktion in der Zieldatenbank, die spezifisch für diese Instanz ist.

  • target – Die zu persistierende gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das InstanceState-Objekt zur Zustandsverwaltung, das mit der Instanz verbunden ist.

Gibt zurück:

Kein Rückgabewert wird von diesem Ereignis unterstützt.

attribut sqlalchemy.orm.MapperEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.MapperEventsDispatch object>

Referenz zurück zur _Dispatch-Klasse.

Bidirektional zu _Dispatch._events

methode sqlalchemy.orm.MapperEvents.instrument_class(mapper: Mapper[_O], class_: Type[_O]) None

Empfängt eine Klasse, wenn der Mapper zum ersten Mal konstruiert wird, bevor die Instrumentierung auf die gemappte Klasse angewendet wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'instrument_class')
def receive_instrument_class(mapper, class_):
    "listen for the 'instrument_class' event"

    # ... (event handling logic) ...

Dieses Ereignis ist die früheste Phase der Mapper-Konstruktion. Die meisten Attribute des Mappers sind noch nicht initialisiert. Um ein Ereignis innerhalb der anfänglichen Mapper-Konstruktion zu empfangen, in dem grundlegende Zustandsinformationen wie die Mapper.attrs-Sammlung verfügbar sind, ist das MapperEvents.after_mapper_constructed()-Ereignis möglicherweise eine bessere Wahl.

Dieser Listener kann entweder auf die Mapper-Klasse insgesamt oder auf jede nicht gemappte Klasse angewendet werden, die als Basis für gemappte Klassen dient (mit dem Flag propagate=True).

Base = declarative_base()


@event.listens_for(Base, "instrument_class", propagate=True)
def on_new_class(mapper, cls_):
    "..."
Parameter:
  • mapper – Der Mapper, der das Ziel dieses Ereignisses ist.

  • class_ – Die gemappte Klasse.

methode sqlalchemy.orm.MapperEvents.mapper_configured(mapper: Mapper[_O], class_: Type[_O]) None

Wird aufgerufen, wenn ein bestimmter Mapper seine eigene Konfiguration im Rahmen des configure_mappers() Aufrufs abgeschlossen hat.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'mapper_configured')
def receive_mapper_configured(mapper, class_):
    "listen for the 'mapper_configured' event"

    # ... (event handling logic) ...

Das Ereignis MapperEvents.mapper_configured() wird für jeden Mapper aufgerufen, der während des Durchlaufs der Funktion configure_mappers() durch die aktuelle Liste der noch nicht konfigurierten Mapper angetroffen wird. configure_mappers() wird typischerweise automatisch aufgerufen, wenn Mappings zum ersten Mal verwendet werden, sowie jedes Mal, wenn neue Mapper verfügbar gemacht wurden und eine neue Mapper-Verwendung erkannt wird.

Wenn das Ereignis aufgerufen wird, sollte sich der Mapper in seinem endgültigen Zustand befinden, aber **ohne Backrefs**, die von anderen Mappern aufgerufen werden könnten; diese könnten während des Konfigurationsvorgangs noch ausstehen. Bidirektionale Beziehungen, die stattdessen über das Argument relationship.back_populates konfiguriert werden, sind **vollständig verfügbar**, da dieser Beziehungsstil nicht auf andere, möglicherweise nicht konfigurierte Mapper angewiesen ist, um zu wissen, dass sie existieren.

Für ein Ereignis, das garantiert, dass **alle** Mapper bereit sind, einschließlich Backrefs, die nur auf anderen Mappings definiert sind, verwenden Sie das Ereignis MapperEvents.after_configured(); dieses Ereignis wird nur aufgerufen, nachdem alle bekannten Mappings vollständig konfiguriert wurden.

Das Ereignis MapperEvents.mapper_configured() wird, im Gegensatz zu MapperEvents.before_configured() oder MapperEvents.after_configured(), für jeden Mapper/jede Klasse einzeln aufgerufen, und der Mapper wird selbst an das Ereignis übergeben. Es wird auch genau einmal für einen bestimmten Mapper aufgerufen. Das Ereignis ist daher nützlich für Konfigurationsschritte, die davon profitieren, nur einmal pro Mapper aufgerufen zu werden und bei denen "Backref"-Konfigurationen nicht unbedingt bereit sein müssen.

Parameter:
  • mapper – der Mapper, der das Ziel dieses Ereignisses ist.

  • class_ – die gemappte Klasse.

Instanzereignisse

Instanzereignisse konzentrieren sich auf die Erstellung von ORM-gemappten Instanzen, einschließlich, wenn sie als transiente Objekte instanziiert werden, wenn sie aus der Datenbank geladen und zu persistenten Objekten werden, sowie wenn Datenbank-Refresh- oder Ablaufoperationen auf dem Objekt stattfinden.

Objektname Beschreibung

InstanceEvents

Definieren Sie ereignisspezifische Informationen für den Objektlebenszyklus.

class sqlalchemy.orm.InstanceEvents

Definieren Sie ereignisspezifische Informationen für den Objektlebenszyklus.

z. B.

from sqlalchemy import event


def my_load_listener(target, context):
    print("on load!")


event.listen(SomeClass, "load", my_load_listener)

Verfügbare Ziele umfassen

  • zugeordnete Klassen

  • nicht zugeordnete Oberklassen von zugeordneten oder noch zuzuordnenden Klassen (mit dem Flag propagate=True)

  • Mapper-Objekte

  • die Mapper-Klasse selbst gibt an, dass für alle Mapper zugehört wird.

Instanzereignisse sind eng mit Mapper-Ereignissen verwandt, aber spezifischer für die Instanz und ihre Instrumentierung als für ihr Persistenzsystem.

Bei Verwendung von InstanceEvents stehen dem listen() Funktionsaufruf mehrere Modifikatoren zur Verfügung.

Parameter:
  • propagate=False – Wenn True, sollte der Ereignis-Listener auf alle erbenden Klassen sowie auf die Klasse angewendet werden, die das Ziel dieses Listeners ist.

  • raw=False – Wenn True, ist das "target"-Argument, das an die entsprechenden Ereignis-Listener-Funktionen übergeben wird, das Management-Objekt InstanceState der Instanz und nicht die gemappte Instanz selbst.

  • restore_load_context=False

    Gilt für die Ereignisse InstanceEvents.load() und InstanceEvents.refresh(). Stellt den Ladekontext des Objekts nach Abschluss des Ereignis-Hooks wieder her, damit fortlaufende Eager-Load-Operationen das Objekt weiterhin korrekt ansteuern. Eine Warnung wird ausgegeben, wenn das Objekt aus einem dieser Ereignisse in einen neuen Ladekontext verschoben wird, wenn dieses Flag nicht gesetzt ist.

    Neu in Version 1.3.14.

Klassensignatur

class sqlalchemy.orm.InstanceEvents (sqlalchemy.event.Events)

attribute sqlalchemy.orm.InstanceEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.InstanceEventsDispatch object>

Referenz zurück zur _Dispatch-Klasse.

Bidirektional zu _Dispatch._events

methode sqlalchemy.orm.InstanceEvents.expire(target: _O, attrs: Iterable[str] | None) None

Empfängt eine Objektinstanz, nachdem ihre Attribute oder eine Teilmenge davon abgelaufen sind.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'expire')
def receive_expire(target, attrs):
    "listen for the 'expire' event"

    # ... (event handling logic) ...

'keys' ist eine Liste von Attributnamen. Wenn None, wurde der gesamte Zustand abgelaufen.

Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • attrs – Sequenz von Attributnamen, die abgelaufen sind, oder None, wenn alle Attribute abgelaufen sind.

methode sqlalchemy.orm.InstanceEvents.first_init(manager: ClassManager[_O], cls: Type[_O]) None

Wird aufgerufen, wenn die erste Instanz einer bestimmten Zuordnung aufgerufen wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'first_init')
def receive_first_init(manager, cls):
    "listen for the 'first_init' event"

    # ... (event handling logic) ...

Dieses Ereignis wird aufgerufen, wenn die `__init__`-Methode einer Klasse zum ersten Mal für diese bestimmte Klasse aufgerufen wird. Das Ereignis wird ausgelöst, bevor `__init__` tatsächlich fortfährt, sowie bevor das Ereignis InstanceEvents.init() ausgelöst wird.

methode sqlalchemy.orm.InstanceEvents.init(target: _O, args: Any, kwargs: Any) None

Empfängt eine Instanz, wenn ihr Konstruktor aufgerufen wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'init')
def receive_init(target, args, kwargs):
    "listen for the 'init' event"

    # ... (event handling logic) ...

Diese Methode wird nur während einer benutzerdefinierten Konstruktion eines Objekts aufgerufen, in Verbindung mit dem Konstruktor des Objekts, z. B. seiner `__init__`-Methode. Sie wird nicht aufgerufen, wenn ein Objekt aus der Datenbank geladen wird; siehe das Ereignis InstanceEvents.load(), um einen Datenbank-Load abzufangen.

Das Ereignis wird aufgerufen, bevor der eigentliche `__init__`-Konstruktor des Objekts aufgerufen wird. Das `kwargs`-Wörterbuch kann direkt geändert werden, um zu beeinflussen, was an `__init__` übergeben wird.

Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • args – Positionsargumente, die an die `__init__`-Methode übergeben wurden. Dies wird als Tupel übergeben und ist derzeit unveränderlich.

  • kwargs – Schlüsselwortargumente, die an die `__init__`-Methode übergeben wurden. Diese Struktur **kann** direkt geändert werden.

methode sqlalchemy.orm.InstanceEvents.init_failure(target: _O, args: Any, kwargs: Any) None

Empfängt eine Instanz, wenn ihr Konstruktor aufgerufen wurde und eine Ausnahme ausgelöst hat.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'init_failure')
def receive_init_failure(target, args, kwargs):
    "listen for the 'init_failure' event"

    # ... (event handling logic) ...

Diese Methode wird nur während einer benutzerdefinierten Konstruktion eines Objekts aufgerufen, in Verbindung mit dem Konstruktor des Objekts, z. B. seiner `__init__`-Methode. Sie wird nicht aufgerufen, wenn ein Objekt aus der Datenbank geladen wird.

Das Ereignis wird ausgelöst, nachdem eine von der `__init__`-Methode ausgelöste Ausnahme abgefangen wurde. Nach Auslösung des Ereignisses wird die ursprüngliche Ausnahme nach außen hin erneut ausgelöst, sodass die Konstruktion des Objekts weiterhin eine Ausnahme auslöst. Die tatsächlich ausgelöste Ausnahme und der Stack-Trace sollten in `sys.exc_info()` vorhanden sein.

Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • args – Positionsargumente, die an die `__init__`-Methode übergeben wurden.

  • kwargs – Schlüsselwortargumente, die an die `__init__`-Methode übergeben wurden.

methode sqlalchemy.orm.InstanceEvents.load(target: _O, context: QueryContext) None

Empfängt eine Objektinstanz, nachdem sie über `__new__` erstellt wurde und nach anfänglicher Attributzuweisung.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'load')
def receive_load(target, context):
    "listen for the 'load' event"

    # ... (event handling logic) ...

Dies geschieht typischerweise, wenn die Instanz basierend auf eingehenden Ergebniszeilen erstellt wird, und wird nur einmal im Lebenszyklus der Instanz aufgerufen.

Warnung

Während eines Ergebniszeilen-Ladevorgangs wird dieses Ereignis aufgerufen, wenn die erste Zeile für diese Instanz verarbeitet wird. Bei Eager Loading mit sammlungsorientierten Attributen wurden die zusätzlichen Zeilen, die geladen/verarbeitet werden, um nachfolgende Sammlungsbestandteile zu laden, noch nicht verarbeitet. Dies hat zur Folge, dass Sammlungen nicht vollständig geladen werden und dass, wenn eine Operation innerhalb dieses Ereignis-Handlers auftritt, die eine weitere Datenbank-Ladeoperation für das Objekt auslöst, der "Ladekontext" für das Objekt geändert werden kann und die bestehenden, noch laufenden Eager-Loader stört.

Beispiele für das, was den "Ladekontext" innerhalb des Ereignis-Handlers ändern kann, sind, aber nicht notwendigerweise darauf beschränkt:

  • Der Zugriff auf verzögerte Attribute, die nicht Teil der Zeile waren, löst eine "Undefer"-Operation aus und aktualisiert das Objekt.

  • Der Zugriff auf Attribute einer geerbten Unterklasse, die nicht Teil der Zeile waren, löst eine Aktualisierungsoperation aus.

Ab SQLAlchemy 1.3.14 wird eine Warnung ausgegeben, wenn dies geschieht. Die Option InstanceEvents.restore_load_context kann für das Ereignis verwendet werden, um diese Warnung zu verhindern; dies stellt sicher, dass der bestehende Ladekontext für das Objekt nach Abschluss des Ereignisses beibehalten wird.

@event.listens_for(SomeClass, "load", restore_load_context=True)
def on_load(instance, context):
    instance.some_unloaded_attribute

Geändert in Version 1.3.14: Hinzugefügt wurden die Flags InstanceEvents.restore_load_context und SessionEvents.restore_load_context, die für "on load"-Ereignisse gelten. Diese stellen sicher, dass der Ladekontext eines Objekts nach Abschluss des Ereignis-Hooks wiederhergestellt wird; eine Warnung wird ausgegeben, wenn sich der Ladekontext des Objekts ändert, ohne dass dieses Flag gesetzt ist.

Das Ereignis InstanceEvents.load() ist auch in einem Klassenmethoden-Decorator-Format namens reconstructor() verfügbar.

Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • context – der QueryContext, der der aktuellen `Query`-Operation entspricht. Dieses Argument kann `None` sein, wenn der Ladevorgang keiner `Query` entspricht, z. B. während Session.merge().

methode sqlalchemy.orm.InstanceEvents.pickle(target: _O, state_dict: _InstanceDict) None

Empfängt eine Objektinstanz, wenn ihr zugehöriger Zustand serialisiert (gepickelt) wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'pickle')
def receive_pickle(target, state_dict):
    "listen for the 'pickle' event"

    # ... (event handling logic) ...
Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • state_dict – das von `__getstate__` zurückgegebene Wörterbuch, das den zu serialisierenden Zustand enthält.

methode sqlalchemy.orm.InstanceEvents.refresh(target: _O, context: QueryContext, attrs: Iterable[str] | None) None

Empfängt eine Objektinstanz, nachdem ein oder mehrere Attribute aus einer Abfrage aktualisiert wurden.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'refresh')
def receive_refresh(target, context, attrs):
    "listen for the 'refresh' event"

    # ... (event handling logic) ...

Kontrastieren Sie dies mit der Methode InstanceEvents.load(), die aufgerufen wird, wenn das Objekt zum ersten Mal aus einer Abfrage geladen wird.

Hinweis

Dieses Ereignis wird während des Ladevorgangs aufgerufen, bevor Eager Loader möglicherweise abgeschlossen wurden, und der Zustand des Objekts ist möglicherweise nicht vollständig. Darüber hinaus platziert die Auslösung von Zeilen-Refresh-Operationen auf dem Objekt das Objekt in einen neuen Ladekontext und stört den bestehenden Ladekontext. Siehe den Hinweis zu InstanceEvents.load(), um Hintergrundinformationen zur Verwendung des Parameters InstanceEvents.restore_load_context zu erhalten, um dieses Szenario zu lösen.

Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • context – der QueryContext, der der aktuellen `Query`-Operation entspricht.

  • attrs – Sequenz von Attributnamen, die gefüllt wurden, oder None, wenn alle Spalten-gemappten, nicht verzögerten Attribute gefüllt wurden.

methode sqlalchemy.orm.InstanceEvents.refresh_flush(target: _O, flush_context: UOWTransaction, attrs: Iterable[str] | None) None

Empfängt eine Objektinstanz, nachdem ein oder mehrere Attribute, die eine spaltengroße Standard- oder onupdate-Behandlung enthalten, während der Persistenz des Objektzustands aktualisiert wurden.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'refresh_flush')
def receive_refresh_flush(target, flush_context, attrs):
    "listen for the 'refresh_flush' event"

    # ... (event handling logic) ...

Dieses Ereignis ist dasselbe wie InstanceEvents.refresh(), wird jedoch innerhalb des Unit-of-Work-Flush-Prozesses aufgerufen und enthält nur Nicht-Primärschlüsselspalten, die spaltengroße Standard- oder Onupdate-Behandlungen aufweisen, einschließlich Python-Aufrufe sowie serverseitige Standards und Trigger, die über die RETURNING-Klausel abgerufen werden können.

Hinweis

Während das Ereignis InstanceEvents.refresh_flush() für ein Objekt ausgelöst wird, das sowohl eingefügt als auch aktualisiert wurde, ist das Ereignis hauptsächlich für den UPDATE-Prozess gedacht; es ist hauptsächlich ein interner Artefakt, dass INSERT-Aktionen dieses Ereignis ebenfalls auslösen können, und beachten Sie, dass **Primärschlüsselspalten für eine eingefügte Zeile explizit von diesem Ereignis ausgeschlossen sind**. Um den neu eingefügten Zustand eines Objekts abzufangen, sind SessionEvents.pending_to_persistent() und MapperEvents.after_insert() bessere Optionen.

Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • flush_context – Internes `UOWTransaction`-Objekt UOWTransaction, das die Details des Flushs behandelt.

  • attrs – Sequenz von Attributnamen, die gefüllt wurden.

methode sqlalchemy.orm.InstanceEvents.unpickle(target: _O, state_dict: _InstanceDict) None

Empfängt eine Objektinstanz, nachdem ihr zugehöriger Zustand deserialisiert (entpickelt) wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass, 'unpickle')
def receive_unpickle(target, state_dict):
    "listen for the 'unpickle' event"

    # ... (event handling logic) ...
Parameter:
  • target – die gemappte Instanz. Wenn das Ereignis mit raw=True konfiguriert ist, ist dies stattdessen das Zustandsmanagement-Objekt InstanceState, das mit der Instanz verknüpft ist.

  • state_dict – das an `__setstate__` gesendete Wörterbuch, das den serialisierten Zustand enthält.

Attributereignisse

Attributereignisse werden ausgelöst, wenn Dinge an einzelnen Attributen von ORM-gemappten Objekten auftreten. Diese Ereignisse bilden die Grundlage für Dinge wie einfache Validierungsfunktionen sowie Backref-Handler.

Objektname Beschreibung

AttributeEvents

Definieren Sie Ereignisse für Objektattribute.

class sqlalchemy.orm.AttributeEvents

Definieren Sie Ereignisse für Objektattribute.

Diese werden typischerweise auf dem klassengebundenen Deskriptor für die Zielklasse definiert.

Um beispielsweise einen Listener zu registrieren, der das Ereignis AttributeEvents.append() empfängt

from sqlalchemy import event


@event.listens_for(MyClass.collection, "append", propagate=True)
def my_append_listener(target, value, initiator):
    print("received append event for target: %s" % target)

Listener haben die Möglichkeit, eine möglicherweise geänderte Version des Werts zurückzugeben, wenn das Flag AttributeEvents.retval an listen() oder listens_for() übergeben wird, wie unten gezeigt, veranschaulicht am Ereignis AttributeEvents.set().

def validate_phone(target, value, oldvalue, initiator):
    "Strip non-numeric characters from a phone number"

    return re.sub(r"\D", "", value)


# setup listener on UserContact.phone attribute, instructing
# it to use the return value
listen(UserContact.phone, "set", validate_phone, retval=True)

Eine Validierungsfunktion wie die obige kann auch eine Ausnahme auslösen, z. B. ValueError, um den Vorgang abzubrechen.

Das Flag AttributeEvents.propagate ist ebenfalls wichtig, wenn Listener auf gemappte Klassen angewendet werden, die auch gemappte Unterklassen haben, wie bei Verwendung von Mapper-Vererbungsmustern.

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

Die vollständige Liste der Modifikatoren, die für die Funktionen listen() und listens_for() verfügbar sind, finden Sie unten.

Parameter:
  • active_history=False – Wenn True, zeigt an, dass das „set“-Ereignis den zu ersetzenden „alten“ Wert bedingungslos erhalten möchte, auch wenn dies das Auslösen von Datenbankladungen erfordert. Beachten Sie, dass active_history auch direkt über column_property() und relationship() gesetzt werden kann.

  • propagate=False – Wenn True, wird die Listener-Funktion nicht nur für das angegebene Klassenattribut, sondern auch für Attribute mit demselben Namen auf allen aktuellen Unterklassen dieser Klasse sowie auf allen zukünftigen Unterklassen dieser Klasse eingerichtet, indem ein zusätzlicher Listener verwendet wird, der auf Instrumentierungsereignisse hört.

  • raw=False – Wenn True, ist das „target“-Argument für das Ereignis das Verwaltungs-Objekt InstanceState und nicht die gemappte Instanz selbst.

  • retval=False – Wenn True, muss das benutzerdefinierte Event-Listening den „value“-Argument aus der Funktion zurückgeben. Dies gibt der Listening-Funktion die Möglichkeit, den Wert zu ändern, der letztendlich für ein „set“- oder „append“-Ereignis verwendet wird.

Klassensignatur

class sqlalchemy.orm.AttributeEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.AttributeEvents.append(target: _O, value: _T, initiator: Event, *, key: EventConstants = EventConstants.NO_KEY) _T | None

Empfangen Sie ein Collection-Append-Ereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'append')
def receive_append(target, value, initiator):
    "listen for the 'append' event"

    # ... (event handling logic) ...

Das Append-Ereignis wird für jedes Element aufgerufen, wenn es zur Collection hinzugefügt wird. Dies geschieht sowohl bei Einzel-Element-Anfügungen als auch bei einer „Bulk-Replace“-Operation.

Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • value – der anzufügende Wert. Wenn dieser Listener mit retval=True registriert ist, muss die Listener-Funktion diesen Wert oder einen neuen Wert zurückgeben, der ihn ersetzt.

  • initiator – Eine Instanz von Event, die die Einleitung des Ereignisses darstellt. Kann von seinem ursprünglichen Wert durch Backref-Handler geändert werden, um die verkettete Ereignisweiterleitung zu steuern, und kann zur Informationsgewinnung über die Quelle des Ereignisses inspiziert werden.

  • key

    Wenn das Ereignis unter Verwendung des Parameters AttributeEvents.include_key auf True gesetzt wurde, ist dies der Schlüssel, der bei der Operation verwendet wird, z. B. collection[some_key_or_index] = value. Der Parameter wird dem Ereignis überhaupt nicht übergeben, wenn AttributeEvents.include_key nicht zum Einrichten des Ereignisses verwendet wurde; dies ermöglicht die Abwärtskompatibilität mit vorhandenen Ereignis-Handlern, die den Parameter key nicht enthalten.

    Neu in Version 2.0.

Gibt zurück:

Wenn das Ereignis mit retval=True registriert wurde, sollte der angegebene Wert oder ein neuer effektiver Wert zurückgegeben werden.

Siehe auch

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

AttributeEvents.bulk_replace()

method sqlalchemy.orm.AttributeEvents.append_wo_mutation(target: _O, value: _T, initiator: Event, *, key: EventConstants = EventConstants.NO_KEY) None

Empfangen Sie ein Collection-Append-Ereignis, bei dem die Collection nicht tatsächlich mutiert wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'append_wo_mutation')
def receive_append_wo_mutation(target, value, initiator):
    "listen for the 'append_wo_mutation' event"

    # ... (event handling logic) ...

Dieses Ereignis unterscheidet sich von AttributeEvents.append() dadurch, dass es für De-Duplizierungs-Collections wie Sets und Dictionaries ausgelöst wird, wenn das Objekt bereits in der Ziel-Collection vorhanden ist. Das Ereignis hat keinen Rückgabewert und die Identität des angegebenen Objekts kann nicht geändert werden.

Das Ereignis wird verwendet, um Objekte in eine Session zu kaskadieren, wenn die Collection bereits über ein Backref-Ereignis mutiert wurde.

Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • value – der Wert, der angefügt würde, wenn das Objekt nicht bereits in der Collection vorhanden wäre.

  • initiator – Eine Instanz von Event, die die Einleitung des Ereignisses darstellt. Kann von seinem ursprünglichen Wert durch Backref-Handler geändert werden, um die verkettete Ereignisweiterleitung zu steuern, und kann zur Informationsgewinnung über die Quelle des Ereignisses inspiziert werden.

  • key

    Wenn das Ereignis unter Verwendung des Parameters AttributeEvents.include_key auf True gesetzt wurde, ist dies der Schlüssel, der bei der Operation verwendet wird, z. B. collection[some_key_or_index] = value. Der Parameter wird dem Ereignis überhaupt nicht übergeben, wenn AttributeEvents.include_key nicht zum Einrichten des Ereignisses verwendet wurde; dies ermöglicht die Abwärtskompatibilität mit vorhandenen Ereignis-Handlern, die den Parameter key nicht enthalten.

    Neu in Version 2.0.

Gibt zurück:

Für dieses Ereignis ist kein Rückgabewert definiert.

Neu in Version 1.4.15.

method sqlalchemy.orm.AttributeEvents.bulk_replace(target: _O, values: Iterable[_T], initiator: Event, *, keys: Iterable[EventConstants] | None = None) None

Empfangen Sie ein Collection-„Bulk-Replace“-Ereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'bulk_replace')
def receive_bulk_replace(target, values, initiator):
    "listen for the 'bulk_replace' event"

    # ... (event handling logic) ...

Dieses Ereignis wird für eine Sequenz von Werten ausgelöst, wenn diese in eine Bulk-Collection-Set-Operation eingehen und vor der Verarbeitung der Werte als ORM-Objekte modifiziert werden können. Dies ist ein „früher Haken“, der ausgeführt wird, bevor die Bulk-Replace-Routine versucht, abzugleichen, welche Objekte bereits in der Collection vorhanden sind und welche durch die Netto-Replace-Operation entfernt werden.

Typischerweise wird diese Methode in Kombination mit der Verwendung des Ereignisses AttributeEvents.append() verwendet. Bei Verwendung beider Ereignisse beachten Sie, dass eine Bulk-Replace-Operation das Ereignis AttributeEvents.append() für alle neuen Elemente auslöst, auch nachdem AttributeEvents.bulk_replace() für die Collection als Ganzes aufgerufen wurde. Um festzustellen, ob ein AttributeEvents.append()-Ereignis Teil eines Bulk-Replace ist, verwenden Sie das Symbol attributes.OP_BULK_REPLACE, um den eingehenden Initiator zu testen.

from sqlalchemy.orm.attributes import OP_BULK_REPLACE


@event.listens_for(SomeObject.collection, "bulk_replace")
def process_collection(target, values, initiator):
    values[:] = [_make_value(value) for value in values]


@event.listens_for(SomeObject.collection, "append", retval=True)
def process_collection(target, value, initiator):
    # make sure bulk_replace didn't already do it
    if initiator is None or initiator.op is not OP_BULK_REPLACE:
        return _make_value(value)
    else:
        return value

Neu seit Version 1.2.

Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • value – eine Sequenz (z. B. eine Liste) der gesetzten Werte. Der Handler kann diese Liste vor Ort ändern.

  • initiator – Eine Instanz von Event, die die Einleitung des Ereignisses darstellt.

  • keys

    Wenn das Ereignis unter Verwendung des Parameters AttributeEvents.include_key auf True gesetzt wurde, ist dies die Sequenz von Schlüsseln, die bei der Operation verwendet wird, typischerweise nur für ein Dictionary-Update. Der Parameter wird dem Ereignis überhaupt nicht übergeben, wenn AttributeEvents.include_key nicht zum Einrichten des Ereignisses verwendet wurde; dies ermöglicht die Abwärtskompatibilität mit vorhandenen Ereignis-Handlern, die den Parameter key nicht enthalten.

    Neu in Version 2.0.

Siehe auch

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

attribute sqlalchemy.orm.AttributeEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.AttributeEventsDispatch object>

Referenz zurück zur _Dispatch-Klasse.

Bidirektional zu _Dispatch._events

method sqlalchemy.orm.AttributeEvents.dispose_collection(target: _O, collection: Collection[Any], collection_adapter: CollectionAdapter) None

Empfangen Sie ein „Collection Dispose“-Ereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'dispose_collection')
def receive_dispose_collection(target, collection, collection_adapter):
    "listen for the 'dispose_collection' event"

    # ... (event handling logic) ...

Dieses Ereignis wird für ein Collection-basiertes Attribut ausgelöst, wenn eine Collection ersetzt wird, d. h.

u1.addresses.append(a1)

u1.addresses = [a2, a3]  # <- old collection is disposed

Die empfangene alte Collection enthält ihre vorherigen Inhalte.

Geändert in Version 1.2: Die an AttributeEvents.dispose_collection() übergebene Collection hat nun ihre Inhalte vor der Entsorgung intakt; zuvor war die Collection leer.

Siehe auch

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

method sqlalchemy.orm.AttributeEvents.init_collection(target: _O, collection: Type[Collection[Any]], collection_adapter: CollectionAdapter) None

Empfangen Sie ein „Collection Init“-Ereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'init_collection')
def receive_init_collection(target, collection, collection_adapter):
    "listen for the 'init_collection' event"

    # ... (event handling logic) ...

Dieses Ereignis wird für ein Collection-basiertes Attribut ausgelöst, wenn die anfängliche „leere Collection“ für ein leeres Attribut zum ersten Mal generiert wird, sowie wenn die Collection durch eine neue ersetzt wird, z. B. über ein Set-Ereignis.

Beispiel: Angenommen, User.addresses ist eine beziehungsbasierte Collection, wird das Ereignis hier ausgelöst

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

und auch während Ersetzungsoperationen

u1.addresses = [a2, a3]  #  <- new collection
Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • collection – die neue Collection. Diese wird immer aus dem generiert, was als relationship.collection_class angegeben wurde, und ist immer leer.

  • collection_adapter – der CollectionAdapter, der den internen Zugriff auf die Collection vermittelt.

Siehe auch

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

AttributeEvents.init_scalar() - „Skalar“-Version dieses Ereignisses.

method sqlalchemy.orm.AttributeEvents.init_scalar(target: _O, value: _T, dict_: Dict[Any, Any]) None

Empfangen Sie ein skalareres „Init“-Ereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'init_scalar')
def receive_init_scalar(target, value, dict_):
    "listen for the 'init_scalar' event"

    # ... (event handling logic) ...

Dieses Ereignis wird ausgelöst, wenn auf ein nicht initialisiertes, nicht persistiertes skalareres Attribut zugegriffen wird, z. B. gelesen.

x = my_object.some_attribute

Das Standardverhalten der ORM, wenn dies bei einem nicht initialisierten Attribut auftritt, ist die Rückgabe des Werts None; beachten Sie, dass dies vom üblichen Verhalten von Python abweicht, das AttributeError auslöst. Das Ereignis hier kann verwendet werden, um anzupassen, welcher Wert tatsächlich zurückgegeben wird, mit der Annahme, dass der Ereignis-Listener einen Standard-Generator widerspiegelt, der auch auf dem Core Column-Objekt konfiguriert ist.

Da ein Standard-Generator auf einer Column auch einen sich ändernden Wert wie einen Zeitstempel erzeugen könnte, kann das Ereignis AttributeEvents.init_scalar() auch verwendet werden, um den neu zurückgegebenen Wert zu **setzen**, so dass eine Core-Level-Standardgenerierungsfunktion effektiv nur einmal ausgelöst wird, aber in dem Moment, in dem auf das Attribut auf dem nicht-persistierten Objekt zugegriffen wird. Normalerweise wird kein Zustand des Objekts geändert, wenn auf ein nicht initialisiertes Attribut zugegriffen wird (deutlich ältere SQLAlchemy-Versionen haben den Zustand des Objekts tatsächlich geändert).

Wenn ein Standard-Generator auf einer Spalte eine bestimmte Konstante zurückgab, könnte ein Handler wie folgt verwendet werden.

SOME_CONSTANT = 3.1415926


class MyClass(Base):
    # ...

    some_attribute = Column(Numeric, default=SOME_CONSTANT)


@event.listens_for(
    MyClass.some_attribute, "init_scalar", retval=True, propagate=True
)
def _init_some_attribute(target, dict_, value):
    dict_["some_attribute"] = SOME_CONSTANT
    return SOME_CONSTANT

Oben initialisieren wir das Attribut MyClass.some_attribute auf den Wert von SOME_CONSTANT. Der obige Code enthält folgende Merkmale:

  • Durch das Setzen des Werts SOME_CONSTANT im gegebenen dict_ zeigen wir an, dass dieser Wert in die Datenbank übernommen werden soll. Dies hat Vorrang vor der Verwendung von SOME_CONSTANT im Standard-Generator für die Column. Das Beispiel active_column_defaults.py unter Attribute Instrumentation veranschaulicht die Verwendung desselben Ansatzes für einen sich ändernden Standard, z. B. einen Zeitstempel-Generator. In diesem speziellen Beispiel ist dies nicht unbedingt erforderlich, da SOME_CONSTANT in beiden Fällen Teil der INSERT-Anweisung wäre.

  • Durch das Setzen des Flags retval=True wird der von der Funktion zurückgegebene Wert vom Attribut-Getter zurückgegeben. Ohne dieses Flag wird das Ereignis als passiver Beobachter angenommen und der Rückgabewert unserer Funktion ignoriert.

  • Das Flag propagate=True ist signifikant, wenn die gemappte Klasse erbende Unterklassen enthält, die diesen Ereignis-Listener ebenfalls nutzen würden. Ohne dieses Flag wird eine erbende Unterklasse unseren Ereignis-Handler nicht verwenden.

Im obigen Beispiel wird das Attribut-Set-Ereignis AttributeEvents.set() sowie die zugehörige Validierungsfunktion, die von validates bereitgestellt wird, **nicht** ausgelöst, wenn wir unseren Wert dem gegebenen dict_ zuweisen. Damit diese Ereignisse als Reaktion auf unseren neu generierten Wert ausgelöst werden, weisen Sie den Wert dem gegebenen Objekt als normale Attribut-Set-Operation zu.

SOME_CONSTANT = 3.1415926


@event.listens_for(
    MyClass.some_attribute, "init_scalar", retval=True, propagate=True
)
def _init_some_attribute(target, dict_, value):
    # will also fire off attribute set events
    target.some_attribute = SOME_CONSTANT
    return SOME_CONSTANT

Wenn mehrere Listener eingerichtet sind, wird die Generierung des Werts durch Weitergabe des von den vorherigen Listenern zurückgegebenen Werts, der retval=True angibt, als value-Argument des nächsten Listeners von einem Listener zum nächsten „verkettet“.

Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • value – der Wert, der zurückgegeben werden soll, bevor dieser Ereignis-Listener aufgerufen wurde. Dieser Wert beginnt als None, ist aber der Rückgabewert der vorherigen Ereignis-Handler-Funktion, wenn mehrere Listener vorhanden sind.

  • dict_ – das Attribut-Dictionary dieses gemappten Objekts. Dies ist normalerweise das __dict__ des Objekts, stellt aber in jedem Fall das Ziel dar, das das Attributsystem verwendet, um auf den tatsächlichen Wert dieses Attributs zuzugreifen. Das Platzieren des Werts in diesem Dictionary hat zur Folge, dass der Wert in der von der Unit of Work generierten INSERT-Anweisung verwendet wird.

Siehe auch

AttributeEvents.init_collection() - Collection-Version dieses Ereignisses

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

Attribute Instrumentation - siehe das Beispiel active_column_defaults.py.

method sqlalchemy.orm.AttributeEvents.modified(target: _O, initiator: Event) None

Empfangen Sie ein „Modified“-Ereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'modified')
def receive_modified(target, initiator):
    "listen for the 'modified' event"

    # ... (event handling logic) ...

Dieses Ereignis wird ausgelöst, wenn die Funktion flag_modified() verwendet wird, um ein Änderungsereignis für ein Attribut auszulösen, ohne dass ein spezifischer Wert gesetzt wurde.

Neu seit Version 1.2.

Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • initiator – Eine Instanz von Event, die die Auslösung des Ereignisses darstellt.

Siehe auch

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

method sqlalchemy.orm.AttributeEvents.remove(target: _O, value: _T, initiator: Event, *, key: EventConstants = EventConstants.NO_KEY) None

Empfängt ein Collection-Entfernungsereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'remove')
def receive_remove(target, value, initiator):
    "listen for the 'remove' event"

    # ... (event handling logic) ...
Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • value – der zu entfernende Wert.

  • initiator – Eine Instanz von Event, die die Auslösung des Ereignisses darstellt. Kann von Backref-Handlern von seinem ursprünglichen Wert geändert werden, um die verkettete Ereignispropagierung zu steuern.

  • key

    Wenn das Ereignis unter Verwendung des Parameters AttributeEvents.include_key auf True gesetzt wird, ist dies der Schlüssel, der in der Operation verwendet wird, z. B. del collection[some_key_or_index]. Der Parameter wird überhaupt nicht an das Ereignis übergeben, wenn AttributeEvents.include_key nicht verwendet wurde, um das Ereignis einzurichten; dies dient der Abwärtskompatibilität mit vorhandenen Ereignishandlern, die den Parameter key nicht enthalten.

    Neu in Version 2.0.

Gibt zurück:

Für dieses Ereignis ist kein Rückgabewert definiert.

Siehe auch

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

method sqlalchemy.orm.AttributeEvents.set(target: _O, value: _T, oldvalue: _T, initiator: Event) None

Empfängt ein Skalar-Set-Ereignis.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'set')
def receive_set(target, value, oldvalue, initiator):
    "listen for the 'set' event"

    # ... (event handling logic) ...
Parameter:
  • target – die Objektinstanz, die das Ereignis empfängt. Wenn der Listener mit raw=True registriert ist, ist dies das InstanceState-Objekt.

  • value – der zu setzende Wert. Wenn dieser Listener mit retval=True registriert ist, muss die Listener-Funktion diesen Wert oder einen neuen Wert, der ihn ersetzt, zurückgeben.

  • oldvalue – der ersetzte vorherige Wert. Dies kann auch das Symbol NEVER_SET oder NO_VALUE sein. Wenn der Listener mit active_history=True registriert ist, wird der vorherige Wert des Attributs aus der Datenbank geladen, wenn der vorhandene Wert derzeit nicht geladen oder abgelaufen ist.

  • initiator – Eine Instanz von Event, die die Auslösung des Ereignisses darstellt. Kann von Backref-Handlern von seinem ursprünglichen Wert geändert werden, um die verkettete Ereignispropagierung zu steuern.

Gibt zurück:

Wenn das Ereignis mit retval=True registriert wurde, sollte der angegebene Wert oder ein neuer effektiver Wert zurückgegeben werden.

Siehe auch

AttributeEvents - Hintergrundinformationen zu Listener-Optionen wie Weiterleitung an Unterklassen.

Abfrageereignisse

Objektname Beschreibung

QueryEvents

Stellt Ereignisse innerhalb der Konstruktion eines Query-Objekts dar.

class sqlalchemy.orm.QueryEvents

Stellt Ereignisse innerhalb der Konstruktion eines Query-Objekts dar.

Legacy-Funktion

Die Ereignismethoden von QueryEvents sind ab SQLAlchemy 2.0 Legacy und gelten nur für die direkte Verwendung des Query-Objekts. Sie werden nicht für 2.0-Style-Anweisungen verwendet. Für Ereignisse, die 2.0-Style ORM-Verwendungen abfangen und ändern, verwenden Sie den Hook SessionEvents.do_orm_execute().

Die Hooks von QueryEvents werden nun durch den Ereignishook SessionEvents.do_orm_execute() ersetzt.

Klassensignatur

class sqlalchemy.orm.QueryEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.QueryEvents.before_compile(query: Query) None

Empfängt das Query-Objekt, bevor es zu einem Core Select-Objekt zusammengesetzt wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeQuery, 'before_compile')
def receive_before_compile(query):
    "listen for the 'before_compile' event"

    # ... (event handling logic) ...

Veraltet seit Version 1.4: Das Ereignis QueryEvents.before_compile() wird durch den viel leistungsfähigeren Hook SessionEvents.do_orm_execute() ersetzt. In Version 1.4 wird das Ereignis QueryEvents.before_compile() **nicht mehr** für ORM-Attributladeoperationen verwendet, wie z. B. das Laden von verzögerten oder abgelaufenen Attributen sowie Beziehungs-Loader. Sehen Sie sich die neuen Beispiele in ORM-Abfrageereignisse an, die neue Wege zur Abfangung und Änderung von ORM-Abfragen zum häufigsten Zweck des Hinzufügens beliebiger Filterkriterien veranschaulichen.

Dieses Ereignis ist dazu gedacht, Änderungen an der gegebenen Abfrage zu ermöglichen

@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

Das Ereignis sollte normalerweise mit dem Parameter retval=True abgehört werden, damit die geänderte Abfrage zurückgegeben werden kann.

Das Ereignis QueryEvents.before_compile() verhindert standardmäßig, dass „baked“ Abfragen eine Abfrage cachen, wenn der Ereignishook ein neues Query-Objekt zurückgibt. Dies wirkt sich sowohl auf die direkte Verwendung der Baked Query-Erweiterung als auch auf ihre Funktionsweise innerhalb von Lazy Loadern und Eager Loadern für Beziehungen aus. Um die zwischengespeicherte Abfrage wiederherzustellen, wenden Sie das Ereignis an, indem Sie das Flag bake_ok hinzufügen

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

Wenn bake_ok auf True gesetzt ist, wird der Ereignishook nur einmal aufgerufen und nicht bei nachfolgenden Aufrufen einer bestimmten Abfrage, die zwischengespeichert wird.

Neu in Version 1.3.11: - Hinzufügen des Flags „bake_ok“ zum Ereignis QueryEvents.before_compile() und Verhindern des Cachings über die „baked“-Erweiterung, wenn der Ereignishandler ein neues Query-Objekt zurückgibt, wenn dieses Flag nicht gesetzt ist.

method sqlalchemy.orm.QueryEvents.before_compile_delete(query: Query, delete_context: BulkDelete) None

Ermöglicht Änderungen am Query-Objekt innerhalb von Query.delete().

Beispielhafte Argumentformen

from sqlalchemy import event


@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) ...

Veraltet seit Version 1.4: Das Ereignis QueryEvents.before_compile_delete() wird durch den viel leistungsfähigeren Hook SessionEvents.do_orm_execute() ersetzt.

Ähnlich wie das Ereignis QueryEvents.before_compile() sollte dieses Ereignis mit retval=True konfiguriert werden, und das geänderte Query-Objekt zurückgegeben werden, wie z. B.:

@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
Parameter:
  • query – eine Query-Instanz; dies ist auch das Attribut .query des gegebenen „delete context“-Objekts.

  • delete_context – ein „delete context“-Objekt, das dieselbe Art von Objekt ist, wie in QueryEvents.after_bulk_delete.delete_context beschrieben.

Neu in Version 1.2.17.

method sqlalchemy.orm.QueryEvents.before_compile_update(query: Query, update_context: BulkUpdate) None

Ermöglicht Änderungen am Query-Objekt innerhalb von Query.update().

Beispielhafte Argumentformen

from sqlalchemy import event


@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) ...

Veraltet seit Version 1.4: Das Ereignis QueryEvents.before_compile_update() wird durch den viel leistungsfähigeren Hook SessionEvents.do_orm_execute() ersetzt.

Ähnlich wie das Ereignis QueryEvents.before_compile() sollte es, wenn das Ereignis zur Änderung des Query-Objekts verwendet werden soll, mit retval=True konfiguriert werden und das geänderte Query-Objekt zurückgegeben werden, wie z. B.:

@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["timestamp"] = datetime.datetime.now(
                datetime.UTC
            )
    return query

Das Wörterbuch .values des „update context“-Objekts kann ebenfalls vor Ort geändert werden, wie oben gezeigt.

Parameter:
  • query – eine Query-Instanz; dies ist auch das Attribut .query des gegebenen „update context“-Objekts.

  • update_context – ein „update context“-Objekt, das dieselbe Art von Objekt ist, wie in QueryEvents.after_bulk_update.update_context beschrieben. Das Objekt hat im UPDATE-Kontext ein Attribut .values, das das Wörterbuch der Parameter ist, die an Query.update() übergeben werden. Dieses Wörterbuch kann geändert werden, um die VALUES-Klausel der resultierenden UPDATE-Anweisung zu ändern.

Neu in Version 1.2.17.

attribute sqlalchemy.orm.QueryEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.QueryEventsDispatch object>

Referenz zurück zur _Dispatch-Klasse.

Bidirektional zu _Dispatch._events

Instrumentierungsereignisse

Definiert das System der Klasseninstrumentierung von SQLAlchemy.

Dieses Modul ist normalerweise für Benutzeranwendungen nicht direkt sichtbar, definiert aber einen großen Teil der Interaktivität des ORM.

instrumentation.py befasst sich mit der Registrierung von Endbenutzerklassen für die Zustandsverfolgung. Es interagiert eng mit state.py und attributes.py, die die Instrumentierung pro Instanz bzw. pro Klassenattribut festlegen.

Das System der Klasseninstrumentierung kann pro Klasse oder global über das Modul sqlalchemy.ext.instrumentation angepasst werden, das die Mittel zur Erstellung und Angabe alternativer Instrumentierungsformen bietet.

Objektname Beschreibung

InstrumentationEvents

Ereignisse im Zusammenhang mit Klasseninstrumentierungsereignissen.

class sqlalchemy.orm.InstrumentationEvents

Ereignisse im Zusammenhang mit Klasseninstrumentierungsereignissen.

Die Listener hier unterstützen die Einrichtung gegen jede Klasse im neuen Stil, d. h. jedes Objekt, das eine Unterklasse von „type“ ist. Ereignisse werden dann für Ereignisse gegen diese Klasse ausgelöst. Wenn das Flag „propagate=True“ an event.listen() übergeben wird, wird das Ereignis auch für Unterklassen dieser Klasse ausgelöst.

Die Python-Eingabe type wird ebenfalls als Ziel akzeptiert, was dazu führt, dass Ereignisse für alle Klassen ausgelöst werden.

Beachten Sie, dass das „propagate“-Flag hier standardmäßig auf True gesetzt ist, im Gegensatz zu anderen klassenbasierten Ereignissen, bei denen es standardmäßig auf False gesetzt ist. Das bedeutet, dass neue Unterklassen ebenfalls Gegenstand dieser Ereignisse sind, wenn ein Listener auf einer Oberklasse eingerichtet wird.

Klassensignatur

class sqlalchemy.orm.InstrumentationEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.InstrumentationEvents.attribute_instrument(cls: ClassManager[_O], key: _KT, inst: _O) None

Wird aufgerufen, wenn ein Attribut instrumentiert wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeBaseClass, 'attribute_instrument')
def receive_attribute_instrument(cls, key, inst):
    "listen for the 'attribute_instrument' event"

    # ... (event handling logic) ...
method sqlalchemy.orm.InstrumentationEvents.class_instrument(cls: ClassManager[_O]) None

Wird aufgerufen, nachdem die gegebene Klasse instrumentiert wurde.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeBaseClass, 'class_instrument')
def receive_class_instrument(cls):
    "listen for the 'class_instrument' event"

    # ... (event handling logic) ...

Um zum ClassManager zu gelangen, verwenden Sie manager_of_class().

method sqlalchemy.orm.InstrumentationEvents.class_uninstrument(cls: ClassManager[_O]) None

Wird aufgerufen, bevor die gegebene Klasse de-instrumentiert wird.

Beispielhafte Argumentformen

from sqlalchemy import event


@event.listens_for(SomeBaseClass, 'class_uninstrument')
def receive_class_uninstrument(cls):
    "listen for the 'class_uninstrument' event"

    # ... (event handling logic) ...

Um zum ClassManager zu gelangen, verwenden Sie manager_of_class().

attribute sqlalchemy.orm.InstrumentationEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.InstrumentationEventsDispatch object>

Referenz zurück zur _Dispatch-Klasse.

Bidirektional zu _Dispatch._events