核心事件¶

本节描述了SQLAlchemy核心中提供的事件接口。有关事件侦听API的介绍,请参阅 事件 . ORM事件在 ORM事件 .

class sqlalchemy.event.base.Events

为特定目标类型定义事件侦听函数。

连接池事件

class sqlalchemy.events.PoolEvents

基地: sqlalchemy.event.base.Events

的可用事件 Pool .

这里的方法定义事件的名称以及传递给侦听器函数的成员的名称。

例如。::

from sqlalchemy import event

def my_on_checkout(dbapi_conn, connection_rec, connection_proxy):
    "handle an on checkout event"

event.listen(Pool, 'checkout', my_on_checkout)

除了接受 Pool 类和 Pool 实例, PoolEvents 也接受 Engine 对象和 Engine 类作为目标,将解析为 .pool 给定引擎的属性或 Pool 班级:

engine = create_engine("postgresql://scott:tiger@localhost/test")

# will associate with engine.pool
event.listen(engine, 'checkout', my_on_checkout)
checkin(dbapi_connection, connection_record)

当连接返回池时调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'checkin')
def receive_checkin(dbapi_connection, connection_record):
    "listen for the 'checkin' event"

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

请注意,连接可能已关闭,如果连接已失效,则可能为“无”。 checkin 不会为分离的连接调用。(他们不回池。)

参数
  • dbapi_connection -- DBAPI连接。

  • connection_record -- 这个 _ConnectionRecord 管理DBAPI连接。

checkout(dbapi_connection, connection_record, connection_proxy)

从池中检索连接时调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'checkout')
def receive_checkout(dbapi_connection, connection_record, connection_proxy):
    "listen for the 'checkout' event"

    # ... (event handling logic) ...
参数
  • dbapi_connection -- DBAPI连接。

  • connection_record -- 这个 _ConnectionRecord 管理DBAPI连接。

  • connection_proxy -- 这个 _ConnectionFairy 对象,该对象将在签出期间代理DBAPI连接的公共接口。

如果你举起 DisconnectionError ,将释放当前连接并检索新连接。所有签出侦听器的处理将中止并使用新连接重新启动。

close(dbapi_connection, connection_record)

当DBAPI连接关闭时调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'close')
def receive_close(dbapi_connection, connection_record):
    "listen for the 'close' event"

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

事件在关闭发生之前发出。

连接的关闭可能会失败;这通常是因为连接已经关闭。如果关闭操作失败,则放弃连接。

这个 close() 事件与仍与池关联的连接相对应。要截获分离连接的关闭事件,请使用 close_detached() .

1.1 新版功能.

close_detached(dbapi_connection)

当分离的DBAPI连接关闭时调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'close_detached')
def receive_close_detached(dbapi_connection):
    "listen for the 'close_detached' event"

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

事件在关闭发生之前发出。

连接的关闭可能会失败;这通常是因为连接已经关闭。如果关闭操作失败,则放弃连接。

1.1 新版功能.

connect(dbapi_connection, connection_record)

此时,首先为给定的 Pool .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'connect')
def receive_connect(dbapi_connection, connection_record):
    "listen for the 'connect' event"

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

此事件允许直接捕获DBAPI模块级别所在的点。 .connect() 方法已用于生成新的DBAPI连接。

参数
  • dbapi_connection -- DBAPI连接。

  • connection_record -- 这个 _ConnectionRecord 管理DBAPI连接。

detach(dbapi_connection, connection_record)

当DBAPI连接与池“分离”时调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'detach')
def receive_detach(dbapi_connection, connection_record):
    "listen for the 'detach' event"

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

此事件在分离发生后发出。连接不再与给定的连接记录关联。

1.1 新版功能.

first_connect(dbapi_connection, connection_record)

第一次从特定的 Pool .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'first_connect')
def receive_first_connect(dbapi_connection, connection_record):
    "listen for the 'first_connect' event"

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

原因 PoolEvents.first_connect() 根据用于所有连接的设置确定特定数据库连接系列的信息。因为一个特别的 Pool 指单个“创建者”功能(根据 Engine 指的是使用的URL和连接选项),通常对单个连接进行观察是有效的,可以安全地假定该连接对所有后续连接都有效,例如数据库版本、服务器和客户端编码设置、排序规则设置以及许多其他连接。

参数
  • dbapi_connection -- DBAPI连接。

  • connection_record -- 这个 _ConnectionRecord 管理DBAPI连接。

invalidate(dbapi_connection, connection_record, exception)

当DBAPI连接要“失效”时调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'invalidate')
def receive_invalidate(dbapi_connection, connection_record, exception):
    "listen for the 'invalidate' event"

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

每当 _ConnectionRecord.invalidate() 方法是从API使用或通过“auto invalidation”调用的,而不使用 soft 标志。

事件发生在最后一次尝试调用之前 .close() 在连接发生时。

参数
  • dbapi_connection -- DBAPI连接。

  • connection_record -- 这个 _ConnectionRecord 管理DBAPI连接。

  • exception -- 与此无效声明的原因相对应的异常对象(如果有)。可能是 None .

0.9.2 新版功能: 添加了对连接无效侦听的支持。

reset(dbapi_connection, connection_record)

在对池连接执行“重置”操作之前调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'reset')
def receive_reset(dbapi_connection, connection_record):
    "listen for the 'reset' event"

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

此事件表示 rollback() 方法在返回到池之前对DBAPI连接调用。“重置”的行为可以控制,包括禁用,使用 reset_on_return 池论证。

这个 PoolEvents.reset() 事件后面通常是 PoolEvents.checkin() 调用事件,除非在重置后立即放弃连接。

参数
  • dbapi_connection -- DBAPI连接。

  • connection_record -- 这个 _ConnectionRecord 管理DBAPI连接。

soft_invalidate(dbapi_connection, connection_record, exception)

当DBAPI连接“软无效”时调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngineOrPool, 'soft_invalidate')
def receive_soft_invalidate(dbapi_connection, connection_record, exception):
    "listen for the 'soft_invalidate' event"

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

每当 _ConnectionRecord.invalidate() 方法是用 soft 标志。

软无效是指当跟踪此连接的连接记录在签入当前连接后强制重新连接。它不会在被调用的点上主动关闭DBAPI连接。

1.0.3 新版功能.

SQL执行和连接事件

class sqlalchemy.events.ConnectionEvents

基地: sqlalchemy.event.base.Events

的可用事件 Connectable ,其中包括 ConnectionEngine .

这里的方法定义事件的名称以及传递给侦听器函数的成员的名称。

事件侦听器可以与任何 Connectable 类或实例,例如 Engine ,例如:

from sqlalchemy import event, create_engine

def before_cursor_execute(conn, cursor, statement, parameters, context,
                                                executemany):
    log.info("Received statement: %s", statement)

engine = create_engine('postgresql://scott:tiger@localhost/test')
event.listen(engine, "before_cursor_execute", before_cursor_execute)

或者用特定的 Connection ::

with engine.begin() as conn:
    @event.listens_for(conn, 'before_cursor_execute')
    def before_cursor_execute(conn, cursor, statement, parameters,
                                    context, executemany):
        log.info("Received statement: %s", statement)

当使用 statement 参数,如in after_cursor_execute()before_cursor_execute()dbapi_error() ,该语句是为传输到DBAPI而准备的准确的SQL字符串。 cursor 在连接中 Dialect .

这个 before_execute()before_cursor_execute() 事件也可以通过 retval=True 标志,允许修改要发送到数据库的语句和参数。这个 before_cursor_execute() 在这里,事件对于向所有执行添加特殊字符串转换(如注释)特别有用:

from sqlalchemy.engine import Engine
from sqlalchemy import event

@event.listens_for(Engine, "before_cursor_execute", retval=True)
def comment_sql_calls(conn, cursor, statement, parameters,
                                    context, executemany):
    statement = statement + " -- some comment"
    return statement, parameters

注解

ConnectionEvents 可以建立在任何组合上 EngineConnection 以及每个类的实例。对于给定的 Connection . 但是,由于性能原因, Connection 对象在实例化时确定其父级 Engine 已建立事件侦听器。事件侦听器添加到 Engine 类或的实例 Engine after 依赖项的实例化 Connection 实例通常 not 在那上面有空 Connection 实例。新添加的侦听器将在 Connection 在父级上建立这些事件侦听器之后创建的实例 Engine 类或实例。

参数

retval=False -- 适用于 before_execute()before_cursor_execute() 只有事件。如果为true,则用户定义的事件函数必须具有返回值,返回值是替换给定语句和参数的参数的元组。有关特定返回参数的描述,请参见这些方法。

after_cursor_execute(conn, cursor, statement, parameters, context, executemany)

在执行后拦截低级的cursor execute()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'after_cursor_execute')
def receive_after_cursor_execute(conn, cursor, statement, parameters, context, executemany):
    "listen for the 'after_cursor_execute' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'after_cursor_execute', named=True)
def receive_after_cursor_execute(**kw):
    "listen for the 'after_cursor_execute' event"
    conn = kw['conn']
    cursor = kw['cursor']

    # ... (event handling logic) ...
参数
  • conn -- Connection 对象

  • cursor -- DBAPI光标对象。如果语句是select,则将有挂起的结果,但不应使用这些结果,因为 ResultProxy .

  • statement -- 传递给DBAPI的字符串SQL语句

  • parameters -- 要传递给的参数的字典、元组或列表 execute()executemany() DBAPI方法 cursor . 在某些情况下 None .

  • context -- ExecutionContext 对象正在使用中。可能是 None .

  • executemany -- 布尔,如果 True 这是一个 executemany() 调用,如果 False 这是一个 execute() 调用。

after_execute(conn, clauseelement, multiparams, params, result)

在执行后拦截高级execute()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'after_execute')
def receive_after_execute(conn, clauseelement, multiparams, params, result):
    "listen for the 'after_execute' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'after_execute', named=True)
def receive_after_execute(**kw):
    "listen for the 'after_execute' event"
    conn = kw['conn']
    clauseelement = kw['clauseelement']

    # ... (event handling logic) ...
参数
before_cursor_execute(conn, cursor, statement, parameters, context, executemany)

在执行前拦截低级cursor execute()事件,接收要针对光标调用的字符串SQL语句和DBAPI特定参数列表。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, parameters, context, executemany):
    "listen for the 'before_cursor_execute' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'before_cursor_execute', named=True)
def receive_before_cursor_execute(**kw):
    "listen for the 'before_cursor_execute' event"
    conn = kw['conn']
    cursor = kw['cursor']

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

此事件是记录和延迟修改SQL字符串的好选择。除了那些特定于目标后端的参数修改之外,它不太适合于参数修改。

可以选择使用 retval=True 标志。这个 statementparameters 在这种情况下,参数应作为两个元组返回::

@event.listens_for(Engine, "before_cursor_execute", retval=True)
def before_cursor_execute(conn, cursor, statement,
                parameters, context, executemany):
    # do something with statement, parameters
    return statement, parameters

参见中的示例 ConnectionEvents .

参数
  • conn -- Connection 对象

  • cursor -- DBAPI光标对象

  • statement -- 字符串SQL语句,用于传递给DBAPI

  • parameters -- 要传递给的参数的字典、元组或列表 execute()executemany() DBAPI方法 cursor . 在某些情况下 None .

  • context -- ExecutionContext 对象正在使用中。可能是 None .

  • executemany -- 布尔,如果 True 这是一个 executemany() 调用,如果 False 这是一个 execute() 调用。

before_execute(conn, clauseelement, multiparams, params)

截获高级execute()事件,接收未编译的SQL构造和其他对象,然后再呈现到SQL中。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'before_execute')
def receive_before_execute(conn, clauseelement, multiparams, params):
    "listen for the 'before_execute' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'before_execute', named=True)
def receive_before_execute(**kw):
    "listen for the 'before_execute' event"
    conn = kw['conn']
    clauseelement = kw['clauseelement']

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

此事件有助于调试SQL编译问题以及对发送到数据库的参数的早期操作,因为此处的参数列表将采用一致的格式。

可以选择使用 retval=True 标志。这个 clauseelementmultiparamsparams 在这种情况下,参数应作为三元组返回::

@event.listens_for(Engine, "before_execute", retval=True)
def before_execute(conn, clauseelement, multiparams, params):
    # do something with clauseelement, multiparams, params
    return clauseelement, multiparams, params
参数
begin(conn)

intercept begin()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'begin')
def receive_begin(conn):
    "listen for the 'begin' event"

    # ... (event handling logic) ...
参数

conn -- Connection 对象

begin_twophase(conn, xid)

intercept开始执行twophase()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'begin_twophase')
def receive_begin_twophase(conn, xid):
    "listen for the 'begin_twophase' event"

    # ... (event handling logic) ...
参数
commit(conn)

intercept commit()事件,由 Transaction .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'commit')
def receive_commit(conn):
    "listen for the 'commit' event"

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

请注意 Pool 也可以在签入时“自动提交”DBAPI连接,如果 reset_on_return 标志设置为值 'commit' . 要拦截此提交,请使用 PoolEvents.reset() 钩子。

参数

conn -- Connection 对象

commit_twophase(conn, xid, is_prepared)

intercept commit&twophase()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'commit_twophase')
def receive_commit_twophase(conn, xid, is_prepared):
    "listen for the 'commit_twophase' event"

    # ... (event handling logic) ...
参数
dbapi_error(conn, cursor, statement, parameters, context, exception)

截获原始DBAPI错误。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'dbapi_error')
def receive_dbapi_error(conn, cursor, statement, parameters, context, exception):
    "listen for the 'dbapi_error' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'dbapi_error', named=True)
def receive_dbapi_error(**kw):
    "listen for the 'dbapi_error' event"
    conn = kw['conn']
    cursor = kw['cursor']

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

0.9 版后已移除: 这个 ConnectionEvents.dbapi_error() 事件已弃用,将在将来的版本中删除。请参阅 ConnectionEvents.handle_error() 事件。

使用从DBAPI本身接收的DBAPI异常实例调用此事件, 之前 在对DBAPI游标执行任何其他操作之前,SQLAlchemy用它自己的异常包装器包装异常;现有事务和游标上的任何状态都将保持有效。

这里的用例是将低级异常处理注入到 Engine ,通常用于日志记录和调试。

警告

代码应该 not 修改任何状态或在此处引发任何异常,因为这将干扰SQLAlchemy的清理和错误处理例程。有关异常修改,请参阅新的 ConnectionEvents.handle_error() 事件。

在此钩子之后,sqlAlchemy可以尝试对连接/光标执行任何数量的操作,包括关闭光标、在无连接执行时回滚事务以及在检测到“disconnect”时处理整个连接池。然后将异常包装在一个SQLAlchemy DBAPI异常包装器中,并重新引发。

参数
  • conn -- Connection 对象

  • cursor -- DBAPI光标对象

  • statement -- 传递给DBAPI的字符串SQL语句

  • parameters -- 要传递给的参数的字典、元组或列表 execute()executemany() DBAPI方法 cursor . 在某些情况下 None .

  • context -- ExecutionContext 对象正在使用中。可能是 None .

  • exception -- 这个 展开的 直接从DBAPI发出的异常。这里的类特定于正在使用的DBAPI模块。

engine_connect(conn, branch)

截获创建新的 Connection .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'engine_connect')
def receive_engine_connect(conn, branch):
    "listen for the 'engine_connect' event"

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

此事件通常作为调用 Engine.connect() 方法。

它不同于 PoolEvents.connect() 方法,它指的是与DBAPI级别的数据库的实际连接;DBAPI连接可以被池化并在许多操作中重用。相比之下,这一事件只涉及更高层次的生产 Connection 围绕这样一个DBAPI连接进行包装。

它也不同于 PoolEvents.checkout() 事件,因为它特定于 Connection 对象,而不是 PoolEvents.checkout() 尽管可以通过 Connection.connection 属性。但请注意,实际上可能有多个 PoolEvents.checkout() 单身生活中的事件 Connection 对象,如果 Connection 无效并重新建立。也可以有多个 Connection 为相同的已签出DBAPI连接生成的对象,如果 Connection 是生产出来的。

参数
  • conn -- Connection 对象。

  • branch -- 如果为真,则这是现有 Connection . 分支是在语句执行过程中生成的,用于调用补充语句,通常是为了执行insert语句而预先执行一个默认值的选择。

0.9.0 新版功能.

参见

断开操作-悲观 -说明如何使用 ConnectionEvents.engine_connect() 以透明地确保池连接已连接到数据库。

PoolEvents.checkout() 单个DBAPI连接的低级池签出事件

ConnectionEvents.set_connection_execution_options() - A的副本 ConnectionConnection.execution_options() 方法被调用。

engine_disposed(engine)

截获时 Engine.dispose() 方法被调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'engine_disposed')
def receive_engine_disposed(engine):
    "listen for the 'engine_disposed' event"

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

这个 Engine.dispose() 方法指示引擎“释放”其连接池(例如 Pool ,并将其替换为新的。处置旧池会导致关闭现有签入连接。新池在首次使用之前不会建立任何新连接。

此事件可用于指示与 Engine 也应该清理干净,记住 Engine 仍然可以用于新请求,在这种情况下,它会重新获取连接资源。

1.0.5 新版功能.

handle_error(exception_context)

截获由处理的所有异常 Connection .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'handle_error')
def receive_handle_error(exception_context):
    "listen for the 'handle_error' event"

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

这包括DBAPI以及SQLAlchemy的语句调用过程中发出的所有异常,包括编码错误和其他语句验证错误。调用事件的其他区域包括事务开始和结束、结果行提取、光标创建。

注意 handle_error() 可能支持新类型的异常和新的调用方案,位于 任何时候 . 使用此事件的代码必须期望在次要版本中出现新的调用模式。

为了支持与异常相对应的各种成员,以及允许事件的可扩展性而不向后不兼容,收到的唯一参数是 ExceptionContext . 此对象包含表示异常详细信息的数据成员。

这个钩子支持的用例包括:

  • 用于日志记录和调试的只读低级异常处理

  • 异常重新写入

  • 建立或禁用连接或拥有的连接池是否因响应特定异常而失效或过期。

当失败操作(如果有)中的光标仍然打开并可访问时,调用钩子。可以在此光标上调用特殊的清理操作;在调用此挂钩之后,sqlAlchemy将尝试关闭此光标。如果连接处于“自动提交”模式,则事务也将在此挂钩范围内保持打开状态;每语句事务的回滚也会在调用挂钩之后发生。

对于检测当前未由SQLAlchemy方言处理的“断开”情况的常见情况,请 ExceptionContext.is_disconnect 标志可以设置为true,这将导致将异常视为断开连接情况,这通常会导致连接池无效::

@event.listens_for(Engine, "handle_error")
def handle_exception(context):
    if isinstance(context.original_exception, pyodbc.Error):
        for code in (
            '08S01', '01002', '08003',
            '08007', '08S02', '08001', 'HYT00', 'HY010'):

            if code in str(context.original_exception):
                context.is_disconnect = True

处理程序函数有两个选项,用于将SQLAlchemy构造的异常替换为用户定义的异常。它可以直接引发这个新的异常,在这种情况下,所有进一步的事件侦听器都将被绕过,并在进行适当的清理之后引发异常:

@event.listens_for(Engine, "handle_error")
def handle_exception(context):
    if isinstance(context.original_exception,
        psycopg2.OperationalError) and \
        "failed" in str(context.original_exception):
        raise MySpecialException("failed operation")

警告

因为 ConnectionEvents.handle_error() 事件特别规定了作为失败语句引发的最终异常重新引发的异常, 堆栈跟踪将产生误导 如果用户定义的事件处理程序本身失败并引发意外的异常;堆栈跟踪可能无法说明失败的实际代码行!建议在此仔细编码,如果发生意外异常,请使用日志记录和/或内联调试。

或者,可以使用“链接”类型的事件处理,方法是将处理程序配置为 retval=True 修饰符并从函数返回新的异常实例。在这种情况下,事件处理将继续进行到下一个处理程序。“链接”异常可使用 ExceptionContext.chained_exception ::

@event.listens_for(Engine, "handle_error", retval=True)
def handle_exception(context):
    if context.chained_exception is not None and \
        "special" in context.chained_exception.message:
        return MySpecialException("failed",
            cause=context.chained_exception)

返回的处理程序 None 可以在链中使用;当处理程序返回时 None ,上一个异常实例(如果有)将维护为传递给下一个处理程序的当前异常。

当引发或返回自定义异常时,sqlAlchemy将引发此新异常,因为它不被任何sqlAlchemy对象包装。如果异常不是 sqlalchemy.exc.StatementError ,某些功能可能不可用;目前这包括ORM的功能,即向自动刷新过程中引发的异常添加有关“自动刷新”的详细提示。

参数

context -- 一个 ExceptionContext 对象。有关所有可用成员的详细信息,请参见此类。

0.9.7 新版功能: 增加了 ConnectionEvents.handle_error() 钩子。

在 1.1 版更改: 这个 handle_error() 事件现在将接收从继承的所有异常 BaseException 包括 SystemExitKeyboardInterrupt . 设置 ExceptionContext.is_disconnectTrue 在这种情况下,默认 ExceptionContext.invalidate_pool_on_disconnectFalse .

在 1.0.0 版更改: 这个 handle_error()Engine 在初始调用期间失败 Engine.connect() 以及当 Connection 对象在重新连接操作期间遇到错误。

在 1.0.0 版更改: 这个 handle_error() 当方言使用 skip_user_error_events 执行选项。这是由打算在特定操作中捕获特定于sqlAlchemy的异常的方言使用的,例如当mysql方言检测到表不在 has_table() 方言方法。在1.0.0之前,实现 handle_error() 需要确保在这些场景中引发的异常不会被修改。

prepare_twophase(conn, xid)

拦截准备阶段()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'prepare_twophase')
def receive_prepare_twophase(conn, xid):
    "listen for the 'prepare_twophase' event"

    # ... (event handling logic) ...
参数
release_savepoint(conn, name, context)

拦截释放_savepoint()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'release_savepoint')
def receive_release_savepoint(conn, name, context):
    "listen for the 'release_savepoint' event"

    # ... (event handling logic) ...
参数
rollback(conn)

intercept rollback()事件,由 Transaction .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'rollback')
def receive_rollback(conn):
    "listen for the 'rollback' event"

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

请注意 Pool 在签入时“自动回滚”DBAPI连接,如果 reset_on_return 标志设置为其默认值 'rollback' . 要拦截此回滚,请使用 PoolEvents.reset() 钩子。

参数

conn -- Connection 对象

rollback_savepoint(conn, name, context)

截获回滚保存点()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'rollback_savepoint')
def receive_rollback_savepoint(conn, name, context):
    "listen for the 'rollback_savepoint' event"

    # ... (event handling logic) ...
参数
rollback_twophase(conn, xid, is_prepared)

intercept rollback兘thophase()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'rollback_twophase')
def receive_rollback_twophase(conn, xid, is_prepared):
    "listen for the 'rollback_twophase' event"

    # ... (event handling logic) ...
参数
savepoint(conn, name)

拦截savepoint()事件。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'savepoint')
def receive_savepoint(conn, name):
    "listen for the 'savepoint' event"

    # ... (event handling logic) ...
参数
  • conn -- Connection 对象

  • name -- 用于保存点的指定名称。

set_connection_execution_options(conn, opts)

截获时 Connection.execution_options() 方法被调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'set_connection_execution_options')
def receive_set_connection_execution_options(conn, opts):
    "listen for the 'set_connection_execution_options' event"

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

此方法是在新的 Connection 已使用新更新的执行选项集合生成,但在 Dialect 已经采取了任何新的选择。

注意,当新的 Connection 是从其父级继承执行选项的 Engine ;若要拦截此条件,请使用 ConnectionEvents.engine_connect() 事件。

参数

0.9.0 新版功能.

set_engine_execution_options(engine, opts)

截获时 Engine.execution_options() 方法被调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'set_engine_execution_options')
def receive_set_engine_execution_options(engine, opts):
    "listen for the 'set_engine_execution_options' event"

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

这个 Engine.execution_options() 方法生成 Engine 存储新选项。那新的 Engine 在这里经过。此方法的一个特殊应用是添加 ConnectionEvents.engine_connect() 给定的事件处理程序 Engine 它会根据- Connection 特定于这些执行选项的任务。

参数

0.9.0 新版功能.

class sqlalchemy.events.DialectEvents

基地: sqlalchemy.event.base.Events

执行替换函数的事件接口。

这些事件允许直接插入和替换与DBAPI交互的关键方言函数。

注解

DialectEvents 应考虑钩子 semi-public 而且是实验性的。这些钩子不用于一般用途,仅用于必须将复杂的DBAPI机制重新声明注入现有方言的情况。对于一般使用语句拦截事件,请使用 ConnectionEvents 接口。

0.9.4 新版功能.

do_connect(dialect, conn_rec, cargs, cparams)

在建立连接之前接收连接参数。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'do_connect')
def receive_do_connect(dialect, conn_rec, cargs, cparams):
    "listen for the 'do_connect' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'do_connect', named=True)
def receive_do_connect(**kw):
    "listen for the 'do_connect' event"
    dialect = kw['dialect']
    conn_rec = kw['conn_rec']

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

返回DBAPI连接以停止进一步的事件调用;将使用返回的连接。

或者,事件可以操作cargs和/或cparams集合;cargs将始终是一个可以就地转换的python列表,cparams是一个python字典。返回none以允许控件传递给下一个事件处理程序,并最终允许方言在给定更新参数的情况下正常连接。

1.0.3 新版功能.

do_execute(cursor, statement, parameters, context)

接收要调用execute()的光标。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'do_execute')
def receive_do_execute(cursor, statement, parameters, context):
    "listen for the 'do_execute' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'do_execute', named=True)
def receive_do_execute(**kw):
    "listen for the 'do_execute' event"
    cursor = kw['cursor']
    statement = kw['statement']

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

返回值true以停止进一步的事件调用,并指示光标已在事件处理程序中执行。

do_execute_no_params(cursor, statement, context)

接收一个光标,使其具有execute(),而不调用任何参数。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'do_execute_no_params')
def receive_do_execute_no_params(cursor, statement, context):
    "listen for the 'do_execute_no_params' event"

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

返回值true以停止进一步的事件调用,并指示光标已在事件处理程序中执行。

do_executemany(cursor, statement, parameters, context)

接收要调用ExecuteMany()的光标。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'do_executemany')
def receive_do_executemany(cursor, statement, parameters, context):
    "listen for the 'do_executemany' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'do_executemany', named=True)
def receive_do_executemany(**kw):
    "listen for the 'do_executemany' event"
    cursor = kw['cursor']
    statement = kw['statement']

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

返回值true以停止进一步的事件调用,并指示光标已在事件处理程序中执行。

do_setinputsizes(inputsizes, cursor, statement, parameters, context)

接收setinputsizes字典以进行可能的修改。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeEngine, 'do_setinputsizes')
def receive_do_setinputsizes(inputsizes, cursor, statement, parameters, context):
    "listen for the 'do_setinputsizes' event"

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

# named argument style (new in 0.9)
@event.listens_for(SomeEngine, 'do_setinputsizes', named=True)
def receive_do_setinputsizes(**kw):
    "listen for the 'do_setinputsizes' event"
    inputsizes = kw['inputsizes']
    cursor = kw['cursor']

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

如果方言使用dbapi,则会发出此事件。 cursor.setinputsizes() 传递特定语句的参数绑定信息的方法。给定的 inputsizes 字典将包含 BindParameter 对象作为键,链接到特定于DBAPI的类型对象作为值;对于未绑定的参数,将它们添加到字典中 None 作为值,这意味着参数不会包含在最终的setinputsizes调用中。该事件可用于检查和/或记录正在绑定的数据类型,以及就地修改字典。可以在此词典中添加、修改或删除参数。调用者通常希望检查 BindParameter.type 给定绑定对象的属性,以决定DBAPI对象。

活动结束后, inputsizes 字典转换为要传递给的适当数据结构 cursor.setinputsizes ;位置绑定参数执行样式的列表,或指定绑定参数执行样式的DBAPI类型对象的字符串参数键字典。

大多数方言 不要使用 这个方法;唯一使用这个钩子的内置方言是cx-oracle方言。这里的钩子是可用的,以便定制如何使用cx_Oracle DBAPI设置数据类型。

1.2.9 新版功能.

模式事件

class sqlalchemy.events.DDLEvents

基地: sqlalchemy.event.base.Events

为模式对象定义事件侦听器,即, SchemaItemSchemaEventTarget 子类,包括 MetaDataTableColumn .

MetaDataTable 支持特定于何时将创建和删除DDL发送到数据库的事件。

当子架构元素与父级相关联时,也会提供附件事件以自定义行为,例如,当 Column 与其关联 Table 当A ForeignKeyConstraintTable 等。

示例使用 after_create 事件:

from sqlalchemy import event
from sqlalchemy import Table, Column, Metadata, Integer

m = MetaData()
some_table = Table('some_table', m, Column('data', Integer))

def after_create(target, connection, **kw):
    connection.execute("ALTER TABLE %s SET name=foo_%s" %
                            (target.name, target.name))

event.listen(some_table, "after_create", after_create)

DDL事件与 DDL 类与 DDLElement DDL子句构造的层次结构,它们本身适合作为侦听器可调用文件:

from sqlalchemy import DDL
event.listen(
    some_table,
    "after_create",
    DDL("ALTER TABLE %(table)s SET name=foo_%(table)s")
)

这里的方法定义事件的名称以及传递给侦听器函数的成员的名称。

为了所有 DDLEvent 事件, propagate=True 关键字参数将确保将给定的事件处理程序传播到使用 Table.tometadata() 方法:

from sqlalchemy import DDL
event.listen(
    some_table,
    "after_create",
    DDL("ALTER TABLE %(table)s SET name=foo_%(table)s"),
    propagate=True
)

new_table = some_table.tometadata(new_metadata)

以上 DDL 对象也将与 Table 对象由表示 new_table .

after_create(target, connection, **kw)

在发出create语句后调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeSchemaClassOrObject, 'after_create')
def receive_after_create(target, connection, **kw):
    "listen for the 'after_create' event"

    # ... (event handling logic) ...
参数
  • target -- 这个 MetaDataTable 对象,它是事件的目标。

  • connection -- 这个 Connection 其中发出了一个或多个create语句。

  • **kw -- 与事件相关的其他关键字参数。此字典的内容可能因版本而异,包括为元数据级事件生成的表列表、checkfirst标志和内部事件使用的其他元素。

event.listen() 也接受 propagate=True 此事件的修饰符;如果为true,则将为目标对象的任何副本建立侦听器函数,即在 Table.tometadata() 使用。

after_drop(target, connection, **kw)

在发出DROP语句后调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeSchemaClassOrObject, 'after_drop')
def receive_after_drop(target, connection, **kw):
    "listen for the 'after_drop' event"

    # ... (event handling logic) ...
参数
  • target -- 这个 MetaDataTable 对象,它是事件的目标。

  • connection -- 这个 Connection 已发出DROP语句的位置。

  • **kw -- 与事件相关的其他关键字参数。此字典的内容可能因版本而异,包括为元数据级事件生成的表列表、checkfirst标志和内部事件使用的其他元素。

event.listen() 也接受 propagate=True 此事件的修饰符;如果为true,则将为目标对象的任何副本建立侦听器函数,即在 Table.tometadata() 使用。

after_parent_attach(target, parent)

调用后 SchemaItem 与父级关联 SchemaItem .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeSchemaClassOrObject, 'after_parent_attach')
def receive_after_parent_attach(target, parent):
    "listen for the 'after_parent_attach' event"

    # ... (event handling logic) ...
参数
  • target -- 目标对象

  • parent -- 目标附加到的父级。

event.listen() 也接受 propagate=True 此事件的修饰符;如果为true,则将为目标对象的任何副本建立侦听器函数,即在 Table.tometadata() 使用。

before_create(target, connection, **kw)

在发出create语句之前调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeSchemaClassOrObject, 'before_create')
def receive_before_create(target, connection, **kw):
    "listen for the 'before_create' event"

    # ... (event handling logic) ...
参数
  • target -- 这个 MetaDataTable 对象,它是事件的目标。

  • connection -- 这个 Connection 其中将发出一个或多个create语句。

  • **kw -- 与事件相关的其他关键字参数。此字典的内容可能因版本而异,包括为元数据级事件生成的表列表、checkfirst标志和内部事件使用的其他元素。

event.listen() 也接受 propagate=True 此事件的修饰符;如果为true,则将为目标对象的任何副本建立侦听器函数,即在 Table.tometadata() 使用。

before_drop(target, connection, **kw)

在发出DROP语句之前调用。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeSchemaClassOrObject, 'before_drop')
def receive_before_drop(target, connection, **kw):
    "listen for the 'before_drop' event"

    # ... (event handling logic) ...
参数
  • target -- 这个 MetaDataTable 对象,它是事件的目标。

  • connection -- 这个 Connection 其中将发出一个或多个drop语句。

  • **kw -- 与事件相关的其他关键字参数。此字典的内容可能因版本而异,包括为元数据级事件生成的表列表、checkfirst标志和内部事件使用的其他元素。

event.listen() 也接受 propagate=True 此事件的修饰符;如果为true,则将为目标对象的任何副本建立侦听器函数,即在 Table.tometadata() 使用。

before_parent_attach(target, parent)

前调用 SchemaItem 与父级关联 SchemaItem .

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeSchemaClassOrObject, 'before_parent_attach')
def receive_before_parent_attach(target, parent):
    "listen for the 'before_parent_attach' event"

    # ... (event handling logic) ...
参数
  • target -- 目标对象

  • parent -- 目标附加到的父级。

event.listen() 也接受 propagate=True 此事件的修饰符;如果为true,则将为目标对象的任何副本建立侦听器函数,即在 Table.tometadata() 使用。

column_reflect(inspector, table, column_info)

Table 正在被反映。

示例参数形式:

from sqlalchemy import event

# standard decorator style
@event.listens_for(SomeSchemaClassOrObject, 'column_reflect')
def receive_column_reflect(inspector, table, column_info):
    "listen for the 'column_reflect' event"

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

通过方言返回的列信息字典,可以修改。字典是在列表的每个元素中返回的 reflection.Inspector.get_columns()

在对该字典执行任何操作之前调用事件,并且可以修改内容。这个 Column 特定参数 infokeyquote 也可以添加到字典中,并将传递给 Column .

请注意,此事件仅在与 Table 全班授课,例如:

from sqlalchemy.schema import Table
from sqlalchemy import event

def listen_for_reflect(inspector, table, column_info):
    "receive a column_reflect event"
    # ...

event.listen(
        Table,
        'column_reflect',
        listen_for_reflect)

…或特定的 Table 实例使用 listeners 论点:

def listen_for_reflect(inspector, table, column_info):
    "receive a column_reflect event"
    # ...

t = Table(
    'sometable',
    autoload=True,
    listeners=[
        ('column_reflect', listen_for_reflect)
    ])

这是因为反射过程是由 autoload=True 在构造函数范围内完成 Table .

event.listen() 也接受 propagate=True 此事件的修饰符;如果为true,则将为目标对象的任何副本建立侦听器函数,即在 Table.tometadata() 使用。

class sqlalchemy.events.SchemaEventTarget

作为目标的元素的基类 DDLEvents 事件。

这包括 SchemaItem 以及 SchemaType .