SQLAlchemy包括一个事件API,它发布了各种钩子到SQLAlchemy核心和ORM的内部。
订阅事件是通过单个API点发生的, listen()
功能,或者 listens_for()
装饰者。这些函数接受一个目标、一个标识要拦截的事件的字符串标识符和一个用户定义的监听函数。这两个函数的附加位置参数和关键字参数可以由特定类型的事件支持,这些事件可以为给定的事件函数指定备用接口,或者根据给定的目标提供有关辅助事件目标的说明。
事件的名称和相应侦听器函数的参数签名是从类绑定规范方法派生的,该方法绑定到文档中描述的标记类。例如,文档 PoolEvents.connect()
指示事件名称为 "connect"
用户定义的侦听器函数应接收两个位置参数:
from sqlalchemy.event import listen
from sqlalchemy.pool import Pool
def my_on_connect(dbapi_con, connection_record):
print("New DBAPI connection:", dbapi_con)
listen(Pool, 'connect', my_on_connect)
和…一起听 listens_for()
装饰符看起来:
from sqlalchemy.event import listens_for
from sqlalchemy.pool import Pool
@listens_for(Pool, "connect")
def my_on_connect(dbapi_con, connection_record):
print("New DBAPI connection:", dbapi_con)
有许多不同的参数样式可以被侦听器函数接受。以 PoolEvents.connect()
,此功能记录为接收 dbapi_connection
和 connection_record
争论。我们可以通过建立一个接受 **keyword
参数,通过传递 named=True
要么 listen()
或 listens_for()
::
from sqlalchemy.event import listens_for
from sqlalchemy.pool import Pool
@listens_for(Pool, "connect", named=True)
def my_on_connect(**kw):
print("New DBAPI connection:", kw['dbapi_connection'])
当使用命名参数传递时,函数参数规范中列出的名称将用作字典中的键。
命名样式按名称传递所有参数,而不考虑函数签名,因此只要名称匹配,特定参数也可以按任意顺序列出::
from sqlalchemy.event import listens_for
from sqlalchemy.pool import Pool
@listens_for(Pool, "connect", named=True)
def my_on_connect(dbapi_connection, **kw):
print("New DBAPI connection:", dbapi_connection)
print("Connection record:", kw['connection_record'])
以上,存在 **kw
告诉 listens_for()
该参数应按名称传递给函数,而不是按位置传递。
0.9.0 新版功能: 增加可选 named
参数调度到事件调用。
这个 listen()
在目标方面功能非常灵活。它通常接受类、这些类的实例以及相关的类或对象,从中可以派生适当的目标。例如,上面提到的 "connect"
事件接受 Engine
类和对象以及 Pool
类和对象:
from sqlalchemy.event import listen
from sqlalchemy.pool import Pool, QueuePool
from sqlalchemy import create_engine
from sqlalchemy.engine import Engine
import psycopg2
def connect():
return psycopg2.connect(username='ed', host='127.0.0.1', dbname='test')
my_pool = QueuePool(connect)
my_engine = create_engine('postgresql://ed@localhost/test')
# associate listener with all instances of Pool
listen(Pool, 'connect', my_on_connect)
# associate listener with all instances of Pool
# via the Engine class
listen(Engine, 'connect', my_on_connect)
# associate listener with my_pool
listen(my_pool, 'connect', my_on_connect)
# associate listener with my_engine.pool
listen(my_engine, 'connect', my_on_connect)
某些侦听器允许将修饰符传递给 listen()
. 这些修饰符有时为侦听器提供备用的调用签名。例如,对于ORM事件,一些事件侦听器可以有一个返回值,用于修改后续处理。默认情况下,任何侦听器都不需要返回值,而是通过传递 retval=True
可以支持此值::
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)
SQLAlchemy core和SQLAlchemy orm都具有多种事件挂钩:
sqlalchemy.event.
listen
(target, identifier, fn, *args, **kw)¶为给定目标注册侦听器函数。
这个 listen()
函数是SQLAlchemy事件系统的主接口的一部分,记录在 事件 .
例如。::
from sqlalchemy import event
from sqlalchemy.schema import UniqueConstraint
def unique_constraint_name(const, table):
const.name = "uq_%s_%s" % (
table.name,
list(const.columns)[0].name
)
event.listen(
UniqueConstraint,
"after_parent_attach",
unique_constraint_name)
给定函数也只能在第一次调用事件时使用 once
论点:
def on_config():
do_config()
event.listen(Mapper, "before_configure", on_config, once=True)
0.9.4 新版功能: 补充 once=True
到 event.listen()
和 event.listens_for()
.
注解
这个 listen()
不能在运行目标事件的同时调用函数。这意味着线程安全,也意味着不能从监听器函数内部为自己添加事件。要运行的事件列表存在于可变集合中,该集合在迭代期间无法更改。
事件注册和删除不打算是一个“高速”操作;它是一个配置操作。对于需要快速与大规模事件关联和解除关联的系统,请使用从单个侦听器内部处理的可变结构。
在 1.0.0 版更改: -A collections.deque()
对象现在用作事件列表的容器,该列表在迭代集合时显式禁止集合突变。
sqlalchemy.event.
listens_for
(target, identifier, *args, **kw)¶将函数修饰为给定目标+标识符的侦听器。
这个 listens_for()
decorator是sqlAlchemy事件系统的主接口的一部分,记录在 事件 .
例如。::
from sqlalchemy import event
from sqlalchemy.schema import UniqueConstraint
@event.listens_for(UniqueConstraint, "after_parent_attach")
def unique_constraint_name(const, table):
const.name = "uq_%s_%s" % (
table.name,
list(const.columns)[0].name
)
给定函数也只能在第一次调用事件时使用 once
论点:
@event.listens_for(Mapper, "before_configure", once=True)
def on_config():
do_config()
0.9.4 新版功能: 补充 once=True
到 event.listen()
和 event.listens_for()
.
参见
listen()
-事件监听概述
sqlalchemy.event.
remove
(target, identifier, fn)¶删除事件侦听器。
这里的参数应该与发送到 listen()
;由于此调用而进行的所有事件注册都将通过调用恢复。 remove()
用同样的论据。
例如。::
# if a function was registered like this...
@event.listens_for(SomeMappedClass, "before_insert", propagate=True)
def my_listener_function(*arg):
pass
# ... it's removed like this
event.remove(SomeMappedClass, "before_insert", my_listener_function)
上面,与 SomeMappedClass
也被传播到 SomeMappedClass
; remove()
函数将恢复所有这些操作。
0.9.0 新版功能.
注解
这个 remove()
不能在运行目标事件的同时调用函数。这对线程安全有影响,也意味着事件不能从侦听器函数内部自行删除。要运行的事件列表存在于可变集合中,该集合在迭代期间无法更改。
事件注册和删除不打算是一个“高速”操作;它是一个配置操作。对于需要快速与大规模事件关联和解除关联的系统,请使用从单个侦听器内部处理的可变结构。
在 1.0.0 版更改: -A collections.deque()
对象现在用作事件列表的容器,该列表在迭代集合时显式禁止集合突变。
参见
sqlalchemy.event.
contains
(target, identifier, fn)¶如果给定的目标/ident/fn设置为侦听,则返回true。
0.9.0 新版功能.