连接池¶
连接池是一种标准技术,用于在内存中维护长时间运行的连接以实现高效重用,以及为应用程序可能同时使用的连接总数提供管理。
特别是对于服务器端 Web 应用程序,连接池是在内存中维护活动数据库连接“池”的标准方法,这些连接在请求之间重复使用。
SQLAlchemy 包括几个与 Engine
集成的连接池实现。它们还可以直接用于希望将池添加到其他普通 DBAPI 方法中的应用程序。
连接池配置¶
由
create_engine()
函数在大多数情况下都有一个 QueuePool
集成,预配置了合理的池默认值。 如果
您阅读本节只是为了了解如何启用池化 - 恭喜!
您已经完成了。
最常见的 QueuePool
调优参数可以作为关键字参数直接传递给 create_engine():
pool_size
、max_overflow
、pool_recycle
和
pool_timeout
。例如:
engine = create_engine(
"postgresql+psycopg2://me@localhost/mydb", pool_size=20, max_overflow=0
)
所有 SQLAlchemy 池实现都有一个共同点,即它们都没有“预先创建”连接 - 所有实现都等到第一次使用后再创建连接。此时,如果没有针对更多连接发出额外的并发签出请求,则不会创建其他连接。这就是为什么 create_engine()
默认使用 QueuePool
是完全可以的
大小为 5,而不考虑应用程序是否真的需要 5 个连接
queued up - 如果应用程序
实际上同时使用了 5 个连接,在这种情况下,使用
small pool 是完全合适的默认行为。
注意
QueuePool
类与 asyncio 不兼容。使用 create_async_engine
创建
而是使用 AsyncEngine
,即 AsyncAdaptedQueuePool
类,该类使用与 asyncio 兼容的队列实现。
切换 Pool 实现¶
使用 create_engine()
的不同类型的池的常用方法
是使用 poolClass
参数。此参数接受从 sqlalchemy.pool
模块导入的类,并为您处理构建池的详细信息。这里的一个常见用例是当要禁用连接池时,这可以通过使用 NullPool
实现来实现:
from sqlalchemy.pool import NullPool
engine = create_engine(
"postgresql+psycopg2://scott:tiger@localhost/test", poolclass=NullPool
)
使用自定义连接函数¶
有关各种连接自定义例程的概要,请参阅自定义 DBAPI connect() 参数/连接例程部分。
构造矿池¶
要单独使用 Pool,creator
函数是唯一需要的参数,首先传递,然后是任何其他选项:
import sqlalchemy.pool as pool
import psycopg2
def getconn():
c = psycopg2.connect(user="ed", host="127.0.0.1", dbname="test")
return c
mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5)
然后,可以使用
Pool.connect()
函数。此方法的返回值是包含在透明代理中的 DBAPI 连接:
# get a connection
conn = mypool.connect()
# use it
cursor_obj = conn.cursor()
cursor_obj.execute("select foo")
透明代理的目的是拦截 close()
调用,这样就不会关闭 DBAPI 连接,而是将其返回到池中:
# "close" the connection. Returns
# it to the pool.
conn.close()
当它被垃圾回收时,代理还会将其包含的 DBAPI 连接返回到池中,尽管在 Python 中并不确定这会立即发生(尽管这在 cPython 中很常见)。但是,不建议使用这种用法,特别是 asyncio DBAPI 驱动程序不支持这种用法。
返回时重置¶
该池包含“return 时重置”行为,该行为将调用 rollback()
方法。
这样,任何现有的事务状态都会从
connection,其中不仅包括未提交的数据,还包括 table 和 row 锁
井。对于大多数 DBAPI,对 rollback()
的调用成本低廉,如果 DBAPI 已经完成了事务,则该方法应该是无作方法。
为非事务性连接禁用 Return 时重置¶
对于此 rollback()
没有用的非常特殊的情况,例如
使用配置为
autocommit 或使用数据库时
没有 ACID 功能(如 MySQL 的 MyISAM 引擎)、
可以禁用 reset-on-return 行为,这通常是为了
性能原因。这可能会受到使用
Pool.reset_on_return
Pool
的参数,也可以从 create_engine()
获得,如
create_engine.pool_reset_on_return
,传递值 None
。
下面的示例将对此进行说明,并将其与
create_engine.isolation_level
参数设置
自动提交
:
non_acid_engine = create_engine(
"mysql://scott:tiger@host/db",
pool_reset_on_return=None,
isolation_level="AUTOCOMMIT",
)
当连接返回到池中时,上述引擎实际上不会执行 ROLLBACK;由于启用了 AUTOCOMMIT,因此驱动程序也不会执行任何 BEGIN作。
自定义 Reset-on-Return 方案¶
对于某些用例,由单个 rollback()
组成的 “reset on return” 可能不够;特别是,使用临时 table 的应用程序可能希望在 Connection Checkin 时自动删除这些 table。一些(但值得注意的是不是全部)后端包含可以在数据库连接范围内“重置”此类表的功能,这可能是连接池重置的理想行为。其他服务器资源(例如准备好的语句句柄和服务器端语句缓存)可能会在签入过程之后仍然存在,这可能是可取的,也可能是不可取的,具体取决于具体情况。同样,一些(但不是全部)后端可能提供重置此状态的方法。已知具有此类重置方案的两个 SQLAlchemy 包含的方言包括 Microsoft SQL Server,其中经常使用一个未记录但广为人知的存储过程,称为 sp_reset_connection
,
以及 PostgreSQL,它有一系列有据可查的命令,包括
DISCARD
RESET、
DEALLOCATE
和 UNLISTEN。
以下示例说明了sp_reset_connection
Microsoft如何使用
PoolEvents.reset()
事件钩子。这
create_engine.pool_reset_on_return
parameter 设置为 None
,以便自定义方案可以完全替换默认行为。这
自定义钩子实现在任何情况下都会调用 .rollback(),
因为 DBAPI 自己的提交/回滚跟踪与事务状态保持一致通常很重要:
from sqlalchemy import create_engine
from sqlalchemy import event
mssql_engine = create_engine(
"mssql+pyodbc://scott:tiger^5HHH@mssql2017:1433/test?driver=ODBC+Driver+17+for+SQL+Server",
# disable default reset-on-return scheme
pool_reset_on_return=None,
)
@event.listens_for(mssql_engine, "reset")
def _reset_mssql(dbapi_connection, connection_record, reset_state):
if not reset_state.terminate_only:
dbapi_connection.execute("{call sys.sp_reset_connection}")
# so that the DBAPI itself knows that the connection has been
# reset
dbapi_connection.rollback()
在 2.0.0b3 版本发生变更: 向 PoolEvents.reset()
事件添加了额外的状态参数,并额外确保为所有 “reset” 事件调用该事件,以便它适合作为自定义 “reset” 处理程序的位置。以前使用 PoolEvents.checkin()
处理程序的方案也仍然可用。
另请参阅
记录 reset-on-return 事件¶
可以设置池事件的日志记录,包括返回时重置
伐木。调试
log 级别以及 sqlalchemy.pool
记录器,或者通过设置
create_engine.echo_pool
设置为“调试”
create_engine()
中:
>>> from sqlalchemy import create_engine
>>> engine = create_engine("postgresql://scott:tiger@localhost/test", echo_pool="debug")
上述池将显示详细的日志记录,包括 reset on return:
>>> c1 = engine.connect()
DEBUG sqlalchemy.pool.impl.QueuePool Created new connection <connection object ...>
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> checked out from pool
>>> c1.close()
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> being returned to pool
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> rollback-on-return
矿池事件¶
连接池支持一个事件接口,该接口允许在第一次连接时、每个新连接时以及在连接签出和签入时执行 hooks。有关详细信息,请参阅 PoolEvents
。
处理断开连接¶
连接池能够刷新单个连接及其整个连接集,将之前池化的连接设置为 “invalid”。一个常见的用例是允许连接池在数据库服务器重新启动时正常恢复,并且所有以前建立的连接都不再有效。有两种方法可以解决这个问题。
断开连接处理 - 悲观¶
悲观方法是指在每个连接池检出开始时对 SQL 连接发出测试语句,以测试数据库连接是否仍然可行。该实现特定于方言,并使用特定于 DBAPI 的 ping 方法,或使用简单的 SQL 语句(如“SELECT 1”)来测试连接的活跃性。
这种方法会给连接签出过程增加一点开销,但除此之外,它是完全消除由于过时的池连接而导致的数据库错误的最简单可靠的方法。调用应用程序无需担心组织作,以便能够从池中签出的过时连接中恢复。
结账时对连接进行悲观测试可以通过使用 Pool.pre_ping
参数来实现,该参数可从 create_engine()
获得
通过 create_engine.pool_pre_ping
参数:
engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)
“pre ping”功能通过调用特定于 DBAPI 的“ping”方法在每种方言的基础上运行,或者如果不可用,将发出相当于“SELECT 1”的 SQL,捕获任何错误并将错误检测为“断开连接”情况。如果 ping / 错误检查确定该连接不可用,则会立即回收该连接,并且所有其他早于当前时间的池连接都将失效,以便下次检出时,它们也将在使用前被回收。
如果在 “pre ping” 运行时数据库仍然不可用,则初始连接将失败,并且连接失败的错误将正常传播。在数据库可用于连接但无法响应“ping”的罕见情况下,“pre_ping”将在放弃之前尝试最多三次,从而传播上次收到的数据库错误。
请务必注意,预 ping 方法不适用于
连接在事务或其他 SQL作过程中断开。如果
当事务正在进行时,数据库变得不可用,则
事务将丢失,并引发数据库错误。 虽然
Connection
对象将检测到 “disconnect” 情况,并且
回收连接并使连接池的其余部分无效
出现此情况时,异常所在的单个作
raised 将丢失,并且由应用程序放弃
作,或者再次重试整个事务。 如果发动机是
使用 DBAPI 级别的自动提交连接进行配置,如
设置事务隔离级别(包括 DBAPI 自动提交),可以在作过程中使用事件透明地重新连接连接。有关示例,请参阅如何自动“重试”语句执行?部分。
对于使用 “SELECT 1” 并捕获错误以检测断开连接的方言,可以使用 DialectEvents.handle_error()
钩子为新的特定于后端的错误消息增强断开连接测试。
自定义 / 遗留悲观 Ping¶
在添加 create_engine.pool_pre_ping
之前,“pre-ping”方法以前是使用 ConnectionEvents.engine_connect()
engine 事件手动执行的。最常见的 recipe 如下,以供参考,以防应用程序已经在使用这样的 recipe,或者需要特殊行为:
from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy import select
some_engine = create_engine(...)
@event.listens_for(some_engine, "engine_connect")
def ping_connection(connection, branch):
if branch:
# this parameter is always False as of SQLAlchemy 2.0,
# but is still accepted by the event hook. In 1.x versions
# of SQLAlchemy, "branched" connections should be skipped.
return
try:
# run a SELECT 1. use a core select() so that
# the SELECT of a scalar value without a table is
# appropriately formatted for the backend
connection.scalar(select(1))
except exc.DBAPIError as err:
# catch SQLAlchemy's DBAPIError, which is a wrapper
# for the DBAPI's exception. It includes a .connection_invalidated
# attribute which specifies if this connection is a "disconnect"
# condition, which is based on inspection of the original exception
# by the dialect in use.
if err.connection_invalidated:
# run the same SELECT again - the connection will re-validate
# itself and establish a new connection. The disconnect detection
# here also causes the whole connection pool to be invalidated
# so that all stale connections are discarded.
connection.scalar(select(1))
else:
raise
上述方法的优点是,我们利用 SQLAlchemy 的工具来检测那些已知指示 “断开连接” 情况的 DBAPI 异常,以及 Engine
对象在发生这种情况时正确使当前连接池失效的能力,并允许当前 Connection
重新验证到新的 DBAPI 连接上。
断开连接处理 - 乐观¶
当未采用悲观处理时,以及当数据库被
在
事务,处理过时/关闭连接的另一种方法是
让 SQLAlchemy 在断开连接时处理它们,此时所有
池中的连接将失效,这意味着它们被假定为
陈旧的,并将在下次结账时刷新。 此行为假定
Pool
与 Engine
结合使用。Engine
具有可以检测断开连接事件并自动刷新池的逻辑。
当 Connection
尝试使用 DBAPI 连接,并引发与“disconnect”事件相对应的异常时,该连接将失效。然后,Connection
调用 Pool.recreate()
方法,有效地使当前未签出的所有连接失效
下次结帐时,它们将被新的替换。 此流程为
由下面的代码示例说明:
from sqlalchemy import create_engine, exc
e = create_engine(...)
c = e.connect()
try:
# suppose the database has been restarted.
c.execute(text("SELECT * FROM table"))
c.close()
except exc.DBAPIError as e:
# an exception is raised, Connection is invalidated.
if e.connection_invalidated:
print("Connection was invalidated!")
# after the invalidate event, a new connection
# starts with a new Pool
c = e.connect()
c.execute(text("SELECT * FROM table"))
上面的示例说明了刷新池不需要特殊干预,在检测到断开连接事件后,刷新池会正常继续。但是,在发生数据库不可用事件时,每个正在使用的每个连接都会引发一个数据库异常。在使用 ORM 会话的典型 Web 应用程序中,上述条件对应于单个请求失败并出现 500 错误,然后 Web 应用程序在此之后继续正常进行。因此,该方法是 “乐观的” ,因为预计不会频繁地重新启动数据库。
设置 Pool Recycle¶
可以增强 “乐观” 方法的另一个设置是设置 pool recycle 参数。此参数可防止池使用已超过特定期限的特定连接,并且适用于数据库后端(如 MySQL),这些后端会在特定时间段后自动关闭已过时的连接:
from sqlalchemy import create_engine
e = create_engine("mysql+mysqldb://scott:tiger@localhost/test", pool_recycle=3600)
在上面,任何已打开超过一小时的 DBAPI 连接都将失效,并在下次结帐时被替换。请注意,失效仅在签出期间发生 - 不发生在保持签出状态的任何连接上。pool_recycle
是 Pool
本身的函数,与是否使用 Engine
无关。
更多关于失效的信息¶
池
提供“连接失效”服务,该服务允许对连接进行显式失效,以及在确定导致连接不可用的情况下自动失效。
“失效”是指从池中删除并丢弃特定的 DBAPI 连接。如果不清楚连接本身可能未关闭,则在此连接上调用 .close()
方法,但是如果此方法失败,则会记录异常,但作仍在继续。
使用 Engine
时,Connection.invalidate()
方法是显式失效的常用入口点。DBAPI 连接可能失效的其他条件包括:
在调用connection.execute()
等方法时引发的 DBAPI 异常(如OperationalError
)被检测为指示所谓的“断开连接”情况。由于 Python DBAPI 没有提供用于确定异常性质的标准系统,因此所有 SQLAlchemy 方言都包含一个名为is_disconnect()
的系统,该系统将检查异常对象的内容,包括字符串消息和其中包含的任何潜在错误代码,以确定此异常是否表明该连接不再可用。如果是这种情况,则调用_ConnectionFairy.invalidate()
方法,然后丢弃 DBAPI 连接。
当连接返回到池中时,调用connection.rollback()
或connection.commit()
方法(如池的“return 时重置”行为所指示)会引发异常。将最后一次尝试在连接上调用.close(),
然后将其丢弃。
当实现PoolEvents.checkout()
的侦听器引发DisconnectionError
异常,表示该连接将不可用,需要进行新的连接尝试。
发生的所有失效都将调用 PoolEvents.invalidate()
事件。
支持新的数据库错误代码,用于断开连接场景¶
SQLAlchemy 方言都包含一个名为 is_disconnect()
的例程,即
每当遇到 DBAPI 异常时调用。DBAPI 异常对象
传递给此方法,然后特定于方言的启发式方法将确定
如果收到的错误代码指示数据库连接已
“disconnected”,或者处于其他不可用状态,这表明它应该
被回收利用。此处应用的启发式方法可以使用
DialectEvents.handle_error()
事件钩子,通常通过拥有的 Engine
对象建立。使用这个钩子,所有
发生的错误会传递一个上下文对象,称为
ExceptionContext 的 ExceptionContext
中。自定义事件钩子可以控制是否应将特定错误视为 “断开连接” 情况,以及此断开连接是否应导致整个连接池失效。
例如,要添加支持以考虑 Oracle Database 驱动程序错误代码
DPY-1001
和 DPY-4011
作为断开连接代码处理,请在创建后将事件处理程序应用于引擎:
import re
from sqlalchemy import create_engine
engine = create_engine(
"oracle+oracledb://scott:tiger@localhost:1521?service_name=freepdb1"
)
@event.listens_for(engine, "handle_error")
def handle_exception(context: ExceptionContext) -> None:
if not context.is_disconnect and re.match(
r"^(?:DPY-1001|DPY-4011)", str(context.original_exception)
):
context.is_disconnect = True
return None
对于引发的所有 Oracle Database 错误,包括对依赖于断开连接错误处理的后端(2.0 中的新增功能)使用池预 ping 功能时捕获的错误,将调用上述错误处理函数。
使用 FIFO 与 LIFO¶
QueuePool
类具有一个名为
QueuePool.use_lifo
,也可以从
create_engine()
通过标志 create_engine.pool_use_lifo
。将此标志设置为 True
会导致池的“队列”行为变为“堆栈”的行为,例如,要返回到池的最后一个连接是下一个请求使用的第一个连接。与池长期以来的先进先出行为相反,该行为会产生串联使用池中的每个连接的循环效应,而 lifo 模式允许多余的连接在池中保持空闲状态,从而允许服务器端超时方案关闭这些连接。FIFO 和 LIFO 之间的区别基本上是池是否希望即使在空闲期间也能保持一整套连接准备就绪:
engine = create_engine("postgreql://", pool_use_lifo=True, pool_pre_ping=True)
在上面,我们还使用了 create_engine.pool_pre_ping
标志,以便连接池可以正常处理从服务器端关闭的连接,并替换为新连接。
请注意,该标志仅适用于 QueuePool
使用。
在 1.3 版本加入.
另请参阅
通过 Multiprocessing 或 os.fork() 使用连接池¶
在使用连接池时,以及使用通过 create_engine()
创建的 Engine
时,池连接不会共享给分叉的进程,这一点至关重要。TCP 连接表示为文件描述符,通常跨进程边界工作,这意味着这将导致代表两个或多个完全独立的 Python 解释器状态对文件描述符的并发访问。
根据驱动程序和作系统的具体情况,这里出现的问题范围从不工作的连接到多个进程同时使用的套接字连接,从而导致消息传递中断(后一种情况通常是最常见的)。
SQLAlchemy Engine
对象引用现有数据库连接的连接池。因此,当此对象复制到子进程时,目标是确保没有数据库连接被转移。有四种常规方法:
使用NullPool
禁用池化。这是最简单的一次性系统,可防止Engine
多次使用任何连接:from sqlalchemy.pool import NullPool engine = create_engine("mysql+mysqldb://user:pass@host/dbname", poolclass=NullPool)
在任何给定的 Engine
上调用Engine.dispose(),
并传递值为
False
,则在子进程的 initialize 阶段。 这是 这样新进程就不会触及父进程的任何连接 而是从新的连接开始。 这是推荐的方法:from multiprocessing import Pool engine = create_engine("mysql+mysqldb://user:pass@host/dbname") def run_in_process(some_data_record): with engine.connect() as conn: conn.execute(text("...")) def initializer(): """ensure the parent proc's database connections are not touched in the new connection pool""" engine.dispose(close=False) with Pool(10, initializer=initializer) as p: p.map(run_in_process, data)
1.4.33 版本中的新功能: 添加了Engine.dispose.close
参数以允许替换子节点中的连接池 进程而不干扰父级使用的连接 过程。
在创建子进程之前直接调用Engine.dispose()。
这也将导致子进程从新的连接池开始,同时确保父连接不会转移到子进程:engine = create_engine("mysql://user:pass@host/dbname") def run_in_process(): with engine.connect() as conn: conn.execute(text("...")) # before process starts, ensure engine.dispose() is called engine.dispose() p = Process(target=run_in_process) p.start()
事件处理程序可以应用于连接池,用于测试跨进程边界共享的连接,并使它们失效:from sqlalchemy import event from sqlalchemy import exc import os engine = create_engine("...") @event.listens_for(engine, "connect") def connect(dbapi_connection, connection_record): connection_record.info["pid"] = os.getpid() @event.listens_for(engine, "checkout") def checkout(dbapi_connection, connection_record, connection_proxy): pid = os.getpid() if connection_record.info["pid"] != pid: connection_record.dbapi_connection = connection_proxy.dbapi_connection = None raise exc.DisconnectionError( "Connection record belongs to pid %s, " "attempting to check out in pid %s" % (connection_record.info["pid"], pid) )
上面,我们使用了一种类似于 断开连接处理 - 悲观地将源自不同父进程的 DBAPI 连接视为“无效”连接,强制池回收连接记录以建立新连接。
上述策略将适应 Engine
的情况
在进程之间共享。仅靠上述步骤不足以完成
在进程边界上共享特定 Connection
的情况;更喜欢将特定 Connection
的范围保留在单个进程(和线程)的本地。此外,不支持直接跨进程边界共享任何类型的正在进行的事务状态,例如已开始事务并引用活动 Connection
实例的 ORM Session
对象;再次首选创建新的
Session
对象。
直接使用 pool 实例¶
池实现可以直接使用,无需引擎。这可用于只希望使用池行为而没有所有其他 SQLAlchemy 功能的应用程序。在下面的示例中,MySQLdb
方言的默认池是使用
create_pool_from_url()
中:
from sqlalchemy import create_pool_from_url
my_pool = create_pool_from_url(
"mysql+mysqldb://", max_overflow=5, pool_size=5, pre_ping=True
)
con = my_pool.connect()
# use the connection
...
# then close it
con.close()
如果未指定要创建的池类型,则将使用方言的默认池类型。要直接指定它,可以使用 poolclass
参数,如下例所示:
from sqlalchemy import create_pool_from_url
from sqlalchemy import NullPool
my_pool = create_pool_from_url("mysql+mysqldb://", poolclass=NullPool)
API 文档 - 可用的矿池实现¶
对象名称 |
描述 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
类 sqlalchemy.pool 中。矿池¶
连接池的抽象基类。
类签名
类sqlalchemy.pool.Pool
(sqlalchemy.log.已识别
,sqlalchemy.event.registry.EventTarget
)-
方法sqlalchemy.pool.Pool 中。
__init__(creator:_CreatorFnType_CreatorWRecFnType, recycle: int = -1, echo: log._EchoFlagType = None, logging_name:strNone=None,reset_on_return:_ResetStyleArgType = True,事件:List[Tuple[_ListenerFnType,str]]None=无,dialect:_ConnDialectDialectNone=无,pre_ping:bool = False, _dispatch:_DispatchCommon[Pool]None=None)¶
构造一个池。
参数
creator¶——返回 DB-API 连接对象的可调用函数。该函数将使用参数调用。
回收¶– 如果设置为非 -1 的值,则连接回收之间的秒数,这意味着在签出时,如果超过此超时,连接将被关闭并替换为新打开的连接。默认为 -1。
logging_name¶– 字符串标识符,将在 “sqlalchemy.pool” 记录器中生成的日志记录的 “name” 字段中使用。默认为对象 id 的十六进制字符串。
回声¶ –
如果为 True,则连接池将记录信息输出,例如连接何时失效以及连接何时回收到默认日志处理程序,默认为sys.stdout
输出。 如果设置为字符串“debug”
,则日志记录将包括池签出和签入。Pool.echo
参数也可以从create_engine()
调用create_engine.echo_pool
参数。
另请参阅
配置日志记录 - 有关如何配置日志记录的更多详细信息。reset_on_return¶ –
确定在连接返回到池时要对连接采取的步骤,这些连接不会由Connection
处理。可通过create_engine()
获取create_engine.pool_reset_on_return
参数。Pool.reset_on_return
可以具有以下任何值:“rollback”
- 在连接上调用 rollback() 以释放锁和事务资源。这是默认值。绝大多数用例应保留此值集。“commit”
- 在连接上调用 commit() 以释放锁和事务资源。对于在发出提交时缓存查询计划的数据库(例如 Microsoft SQL Server),此处的提交可能是可取的。但是,此值比 'rollback' 更危险,因为事务中存在的任何数据更改都是无条件提交的。无
- 不对连接执行任何作。 如果数据库/DBAPI 始终在纯 “autocommit” 模式下工作,或者如果 自定义重置处理程序是使用PoolEvents.reset()
事件处理程序。True
- 与 'rollback' 相同,这是为了向后兼容。False
- 与 None 相同,这是为了向后兼容。
要进一步自定义 reset on return,请使用 可以使用PoolEvents.reset()
事件钩子,它可以执行重置时所需的任何连接活动。
events¶ —— 一个 2 元组的列表,每个元组的形式(callable, target),
它将被传递给listen()
在施工时。 因此,事件侦听器 可以在应用 dialect 级别的侦听器之前通过create_engine()
进行分配。
dialect¶– 一种Dialect
,它将处理在 DBAPI 连接上调用 rollback()、close() 或 commit() 的工作。如果省略,则使用内置的 “stub” 方言。使用create_engine()
的应用程序不应使用此参数,因为它由引擎创建策略处理。pre_ping¶ –
如果为 True,则池将在签出时对连接发出“ping”(通常为“SELECT 1”,但特定于方言),以测试连接是否处于活动状态。否则,将透明地重新连接连接,成功后,在该时间戳之前建立的所有其他池连接都将失效。要求同时传递方言来解释断开连接错误。
在 1.2 版本加入.
-
方法sqlalchemy.pool.Pool 中。
connect()PoolProxiedConnection ¶
从池中返回 DBAPI 连接。
该连接被检测为,当其close()
方法,则连接将返回到池中。
-
方法sqlalchemy.pool.Pool 中。
dispose()无 ¶
处理此池。
此方法使签出连接保持打开状态,因为它只影响池中处于空闲状态的连接。
另请参阅
-
-
类 sqlalchemy.pool 中。队列池¶
A泳池
这会对打开的连接数施加限制。QueuePool
是用于除 SQLite 之外的所有Engine
对象的默认池实现,带有 :memory:
数据库。QueuePool
类与 asyncio 和create_async_engine()
中。 这 如果未指定其他类型的池,则在使用create_async_engine()
时自动使用AsyncAdaptedQueuePool
类。-
方法sqlalchemy.pool.QueuePool 中。
__init__(creator:_CreatorFnType_CreatorWRecFnType, pool_size: int = 5, max_overflow: int = 10, timeout: float = 30.0, use_lifo: bool = False, **kw: Any)¶
构造 QueuePool。
参数
creator¶– 一个可调用的函数,返回一个 DB-API 连接对象,与Pool.creator
相同。
pool_size¶ – 要维护的矿池的大小, 默认为 5。这是 将永久保留在池中。请注意,池 从没有连接开始;一旦此连接数 请求时,将保留该数量的连接。pool_size
可以设置为 0 以表示没有大小限制;要禁用池化,请使用NullPool
相反。
max_overflow¶– 最大溢出大小的 池。当签出的连接数达到 size 设置为 pool_size,则额外的连接将为 返回到此限制。当这些额外的连接 返回到池中,则断开连接,并且 丢弃。因此,总数 池允许的并发连接数为 pool_size + max_overflow,并且池将允许的 “休眠” 连接总数为 pool_size。max_overflow 可以设置为 -1 以表示无溢出限制;无限制 将放置在并发总数上 连接。默认值为 10。
timeout¶— 在放弃返回连接之前等待的秒数。默认为 30.0。这可以是浮点数,但受 Python 时间函数的限制,在几十毫秒内可能不可靠。use_lifo¶ –
检索连接时使用 LIFO (后进先出) 而不是 FIFO (先进先出)。使用 LIFO,服务器端超时方案可以减少非高峰使用期间使用的连接数。在规划服务器端超时时,请确保使用回收或 pre-ping 策略来正常处理过时的连接。
在 1.3 版本加入.
kw¶– 其他关键字参数,包括Pool.recycle
、Pool.echo
、Pool.reset_on_return
和其他 API 将传递给Pool
构造函数。
-
方法sqlalchemy.pool.QueuePool 中。
dispose()无 ¶
处理此池。
此方法使签出连接保持打开状态,因为它只影响池中处于空闲状态的连接。
另请参阅
-
-
类 sqlalchemy.pool 中。AsyncAdaptedQueuePool¶ QueuePool
的 asyncio 兼容版本。
当使用从create_async_engine()
生成的AsyncEngine
引擎时,默认使用此池。 它使用 asyncio 兼容的队列实现,该实现不使用线程。锁定
。AsyncAdaptedQueuePool
的参数和作与QueuePool
的参数和作相同。
-
类 sqlalchemy.pool 中。SingletonThreadPool(单例线程池)¶
一个 Pool,它为每个线程维护一个连接。
为每个线程维护一个连接,从不将连接移动到创建该连接的线程以外的线程。
警告SingletonThreadPool
将调用.close()
在超出 size 设置的任意连接上pool_size
,例如,如果线程标识具有更多唯一性 比使用pool_size
状态。此清理是不确定的,并且对链接到这些线程身份的连接当前是否正在使用不敏感。SingletonThreadPool
可能会在将来的版本中得到改进,但在当前状态下,它通常仅用于使用 SQLite:memory:
数据库的测试场景,不建议用于生产环境。SingletonThreadPool
类与 asyncio 和create_async_engine()
不兼容。
选项与Pool
的选项相同,并且:
参数
pool_size¶– 一次保持连接的线程数。默认为 5。
当使用基于内存的数据库时,SQLite 方言会自动使用SingletonThreadPool
。请参阅 SQLite。-
方法sqlalchemy.pool.SingletonThreadPool.
connect(PoolProxiedConnection ¶
从池中返回 DBAPI 连接。
该连接被检测为,当其close()
方法,则连接将返回到池中。
-
方法sqlalchemy.pool.SingletonThreadPool.
dispose()None ¶
处理此池。
-
方法sqlalchemy.pool.SingletonThreadPool.
recreate()SingletonThreadPool ¶
返回一个新的 Pool,该 Pool 与此Pool
具有相同的类,并配置了相同的创建参数。
-
类 sqlalchemy.pool 中。AssertionPool(断言池)¶
在任何给定时间最多允许一个签出连接的Pool
。
如果一次签出多个连接,这将引发异常。对于调试使用比所需连接数更多的代码很有用。AssertionPool
类与 asyncio 和create_async_engine()
中。-
方法sqlalchemy.pool.AssertionPool.
dispose()None ¶
处理此池。
此方法使签出连接保持打开状态,因为它只影响池中处于空闲状态的连接。
另请参阅
-
方法sqlalchemy.pool.AssertionPool.
recreate()AssertionPool ¶
返回一个新的 Pool,该 Pool 与此Pool
具有相同的类,并配置了相同的创建参数。
-
-
类 sqlalchemy.pool 中。空池¶
不池连接的 Pool。
相反,它实际上是在每次打开/关闭每个连接时打开和关闭底层 DB-API 连接。
此 Pool 实现不支持与 Reconnect 相关的功能,例如recycle
和 connection invalidation,因为没有持续保留任何连接。NullPool
类与 asyncio 和create_async_engine()
中。-
方法sqlalchemy.pool.NullPool 中。
dispose()无 ¶
处理此池。
此方法使签出连接保持打开状态,因为它只影响池中处于空闲状态的连接。
另请参阅
-
-
类 sqlalchemy.pool 中。静态池¶
一个 Pool 只有一个连接,用于所有请求。
与 Reconnect 相关的功能,例如recycle
和 connection invalidation(也用于支持自动重新连接)目前仅部分支持,可能不会产生良好的结果。StaticPool
类与 asyncio 和create_async_engine()
中。-
方法sqlalchemy.pool.StaticPool 中。
dispose()无 ¶
处理此池。
此方法使签出连接保持打开状态,因为它只影响池中处于空闲状态的连接。
另请参阅
-
方法sqlalchemy.pool.StaticPool 中。
recreate()StaticPool ¶
返回一个新的 Pool,该 Pool 与此Pool
具有相同的类,并配置了相同的创建参数。
-
-
类 sqlalchemy.pool 中。ManagesConnection(管理连接)¶
两个连接管理接口的通用基础PoolProxiedConnection
和ConnectionPoolEntry 的 PoolEntry
。
这两个对象通常通过连接池事件钩子在面向公众的 API 中公开,记录在PoolEvents
中。
2.0 版的新Function。-
属性sqlalchemy.pool.ManagesConnection.
dbapi_connection:D BAPIConnectionNone¶
对正在跟踪的实际 DBAPI 连接的引用。
这是一个符合 PEP 249 的对象,对于传统的同步样式 dialects 由第三方提供 正在使用的 DBAPI 实现。 对于 asyncio dialects,实现 通常是 SQLAlchemy 方言提供的适配器对象 本身;底层 asyncio 对象可通过ManagesConnection.driver_connection
属性。
SQLAlchemy 的 DBAPI 连接接口基于DBAPIConnection
协议对象
-
属性sqlalchemy.pool.ManagesConnection.
driver_connection:AnyNone¶
Python DBAPI 或数据库驱动程序使用的“驱动程序级别”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将 与 的对象相同ManagesConnection.dbapi_connection
。对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终 “connection” 对象,例如asyncpg。Connection
对象,该对象将没有标准的 pep-249 方法。
在 1.4.24 版本加入.
-
属性sqlalchemy.pool.ManagesConnection.
信息¶
与此ManagesConnection
实例引用的基础 DBAPI 连接关联的信息字典,允许用户定义的数据与连接相关联。
此字典中的数据在 DBAPI 连接本身的生命周期内是持久的,包括跨池签入和签出。当连接失效并替换为新连接时,将清除此字典。
对于未与ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它已分离),则 attribute 返回一个本地字典ConnectionPoolEntry 的 ConnectionPoolEntry
中。因此,ManagesConnection.info
属性将始终提供 Python 字典。
-
methodsqlalchemy.pool.ManagesConnection.
invalidate(e:BaseExceptionNone=None, soft: bool = False)None ¶
将托管连接标记为无效。
另请参阅
-
属性sqlalchemy.pool.ManagesConnection.
record_info¶
与此关联的持久信息字典ManagesConnection 的 ManagesConnection
中。
与ManagesConnection.info
字典不同,此字典的生存期是ConnectionPoolEntry
的生存期 谁拥有它;因此,此字典将在 特定条目的重新连接和连接失效 在连接池中。
对于未与ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它已分离),该属性将返回 None。与ManagesConnection.info
形成对比 dictionary 中,它永远不会是 None。
-
-
类 sqlalchemy.pool 中。ConnectionPoolEntry¶
代表Pool
实例维护单个数据库连接的对象的接口。ConnectionPoolEntry
对象表示池的特定连接的长期维护,包括使该连接过期或失效,以将其替换为新连接,该连接将继续由同一ConnectionPoolEntry
维护 实例。与PoolProxiedConnection 相比,PoolProxiedConnection
是短期的每次签出连接管理器,此对象在连接池中特定 “slot” 的生命周期内持续存在。ConnectionPoolEntry
对象对面向公众的大多数情况下是可见的 API 代码(当它被投递到连接池事件钩子时,例如PoolEvents.connect()
和PoolEvents.checkout() 的 PoolEvents.checkout()
进行访问。
2.0 版中的新功能:ConnectionPoolEntry
为_ConnectionRecord
内部类提供面向公众的接口。-
方法sqlalchemy.pool.ConnectionPoolEntry.
close()None ¶
关闭由此连接池条目管理的 DBAPI 连接。
-
属性sqlalchemy.pool.ConnectionPoolEntry.
dbapi_connection:D BAPIConnectionNone¶
对正在跟踪的实际 DBAPI 连接的引用。
这是一个符合 PEP 249 的对象,对于传统的同步样式 dialects 由第三方提供 正在使用的 DBAPI 实现。 对于 asyncio dialects,实现 通常是 SQLAlchemy 方言提供的适配器对象 本身;底层 asyncio 对象可通过ManagesConnection.driver_connection
属性。
SQLAlchemy 的 DBAPI 连接接口基于DBAPIConnection
协议对象
-
属性sqlalchemy.pool.ConnectionPoolEntry.
driver_connection:AnyNone¶
Python DBAPI 或数据库驱动程序使用的“驱动程序级别”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将 与 的对象相同ManagesConnection.dbapi_connection
。对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终 “connection” 对象,例如asyncpg。Connection
对象,该对象将没有标准的 pep-249 方法。
在 1.4.24 版本加入.
-
属性sqlalchemy.pool.ConnectionPoolEntry.
in_use¶
返回 True,表示连接当前已签出
-
属性sqlalchemy.pool.ConnectionPoolEntry.
信息¶
继承自ManagesConnection
的ManagesConnection.info
属性
与此ManagesConnection
实例引用的基础 DBAPI 连接关联的信息字典,允许用户定义的数据与连接相关联。
此字典中的数据在 DBAPI 连接本身的生命周期内是持久的,包括跨池签入和签出。当连接失效并替换为新连接时,将清除此字典。
对于未与ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它已分离),则 attribute 返回一个本地字典ConnectionPoolEntry 的 ConnectionPoolEntry
中。因此,ManagesConnection.info
属性将始终提供 Python 字典。
-
methodsqlalchemy.pool.ConnectionPoolEntry.
invalidate(e:BaseExceptionNone=None, soft: bool = False)None ¶
继承自ManagesConnection.invalidate()
ManagesConnection
的方法
将托管连接标记为无效。
另请参阅
-
属性sqlalchemy.pool.ConnectionPoolEntry.
record_info¶
继承自ManagesConnection
的ManagesConnection.record_info
属性
与此关联的持久信息字典ManagesConnection 的 ManagesConnection
中。
与ManagesConnection.info
字典不同,此字典的生存期是ConnectionPoolEntry
的生存期 谁拥有它;因此,此字典将在 特定条目的重新连接和连接失效 在连接池中。
对于未与ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它已分离),该属性将返回 None。与ManagesConnection.info
形成对比 dictionary 中,它永远不会是 None。
-
-
类 sqlalchemy.pool 中。PoolProxiedConnection(池代理连接)¶
用于 PEP 249 DBAPI 连接的类似连接的适配器,其中包括特定于Pool
实现的其他方法。PoolProxiedConnection
是内部_ConnectionFairy
实现对象的面向公众的接口;熟悉_ConnectionFairy
的用户可以将此对象视为等效对象。
2.0 版中的新功能:PoolProxiedConnection
为_ConnectionFairy
内部类提供面向公众的接口。
成员
close()、dbapi_connection、detach()、driver_connection、info、invalidate()、is_detached、is_valid record_info-
方法sqlalchemy.pool.PoolProxiedConnection.
close()None ¶
将此连接释放回池中。PoolProxiedConnection.close()
方法隐藏了 PEP 249.close()
方法,将其行为更改为 将代理连接释放回连接池。
释放到池后,连接是在 Python 进程中保持“打开”和池化状态,还是实际关闭并从 Python 进程中删除,取决于正在使用的池实现及其配置和当前状态。
-
属性sqlalchemy.pool.PoolProxiedConnection.
dbapi_connection:D BAPIConnectionNone¶
对正在跟踪的实际 DBAPI 连接的引用。
这是一个符合 PEP 249 的对象,对于传统的同步样式 dialects 由第三方提供 正在使用的 DBAPI 实现。 对于 asyncio dialects,实现 通常是 SQLAlchemy 方言提供的适配器对象 本身;底层 asyncio 对象可通过ManagesConnection.driver_connection
属性。
SQLAlchemy 的 DBAPI 连接接口基于DBAPIConnection
协议对象
-
方法sqlalchemy.pool.PoolProxiedConnection.
detach()无 ¶
将此连接与其 Pool 分开。
这意味着连接在关闭时将不再返回到池中,而是将真正关闭。关联的ConnectionPoolEntry
将与此 DBAPI 连接取消关联。
请注意,在分离后,可能会违反 Pool 实现施加的任何整体连接限制约束,因为分离的连接已从池的知识和控制中删除。
-
属性sqlalchemy.pool.PoolProxiedConnection.
driver_connection:AnyNone¶
Python DBAPI 或数据库驱动程序使用的“驱动程序级别”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将 与 的对象相同ManagesConnection.dbapi_connection
。对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终 “connection” 对象,例如asyncpg。Connection
对象,该对象将没有标准的 pep-249 方法。
在 1.4.24 版本加入.
-
属性sqlalchemy.pool.PoolProxiedConnection.
信息¶
继承自ManagesConnection
的ManagesConnection.info
属性
与此ManagesConnection
实例引用的基础 DBAPI 连接关联的信息字典,允许用户定义的数据与连接相关联。
此字典中的数据在 DBAPI 连接本身的生命周期内是持久的,包括跨池签入和签出。当连接失效并替换为新连接时,将清除此字典。
对于未与ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它已分离),则 attribute 返回一个本地字典ConnectionPoolEntry 的 ConnectionPoolEntry
中。因此,ManagesConnection.info
属性将始终提供 Python 字典。
-
methodsqlalchemy.pool.PoolProxiedConnection.
invalidate(e:BaseExceptionNone=None, soft: bool = False)None ¶
继承自ManagesConnection.invalidate()
ManagesConnection
的方法
将托管连接标记为无效。
另请参阅
-
属性sqlalchemy.pool.PoolProxiedConnection.
is_detached¶
如果此PoolProxiedConnection
与其池分离,则返回 True。
-
属性sqlalchemy.pool.PoolProxiedConnection.
is_valid¶
如果此PoolProxiedConnection
仍引用活动的 DBAPI 连接,则返回 True。
-
属性sqlalchemy.pool.PoolProxiedConnection.
record_info¶
继承自ManagesConnection
的ManagesConnection.record_info
属性
与此关联的持久信息字典ManagesConnection 的 ManagesConnection
中。
与ManagesConnection.info
字典不同,此字典的生存期是ConnectionPoolEntry
的生存期 谁拥有它;因此,此字典将在 特定条目的重新连接和连接失效 在连接池中。
对于未与ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它已分离),该属性将返回 None。与ManagesConnection.info
形成对比 dictionary 中,它永远不会是 None。
-
-
类 sqlalchemy.pool 中。_ConnectionFairy¶
代理 DBAPI 连接并提供取消引用时返回支持。
这是Pool
实现使用的内部对象,用于为该Pool
提供的 DBAPI 连接提供上下文管理。此类的面向公众的接口由PoolProxiedConnection
类描述。有关公共 API 的详细信息,请参阅该类。
“fairy”这个名字的灵感来自于_ConnectionFairy
对象的生命周期是暂时的,因为它仅在从池中签出的特定 DBAPI 连接的长度内持续,此外,作为透明代理,它几乎是不可见的。
类签名
类sqlalchemy.pool._ConnectionFairy
(sqlalchemy.pool.base.PoolProxiedConnection
)
-
类 sqlalchemy.pool 中。_ConnectionRecord¶
在引用池化连接的连接池中维护一个位置。
这是Pool
实现使用的内部对象,用于为该Pool
维护的 DBAPI 连接提供上下文管理。此类的面向公众的接口由ConnectionPoolEntry
类描述。有关公共 API 的详细信息,请参阅该类。
类签名
类sqlalchemy.pool._ConnectionRecord
(sqlalchemy.pool.base.ConnectionPoolEntry
)