SQLAlchemy 2.0 文档
SQLAlchemy Core
- SQL 语句和表达式 API
- Schema 定义语言
- SQL 数据类型对象
- 引擎和连接使用
- 引擎配置
- 使用引擎和连接
- 连接池¶
- 连接池配置
- 切换池实现
- 使用自定义连接函数
- 构建池
- 返回时重置
- 池事件
- 处理断开连接
- 使用 FIFO 与 LIFO
- 将连接池与多进程或 os.fork() 一起使用
- 直接使用池实例
- API 文档 - 可用池实现
池
QueuePool
AsyncAdaptedQueuePool
SingletonThreadPool
AssertionPool
NullPool
StaticPool
ManagesConnection
ConnectionPoolEntry
PoolProxiedConnection
PoolProxiedConnection.close()
PoolProxiedConnection.dbapi_connection
PoolProxiedConnection.detach()
PoolProxiedConnection.driver_connection
PoolProxiedConnection.info
PoolProxiedConnection.invalidate()
PoolProxiedConnection.is_detached
PoolProxiedConnection.is_valid
PoolProxiedConnection.record_info
_ConnectionFairy
_ConnectionRecord
- Core 事件
- Core API 基础知识
项目版本
- 上一篇: 使用引擎和连接
- 下一篇: Core 事件
- 上一级: 首页
- 本页内容
- 连接池
- 连接池配置
- 切换池实现
- 使用自定义连接函数
- 构建池
- 返回时重置
- 池事件
- 处理断开连接
- 使用 FIFO 与 LIFO
- 将连接池与多进程或 os.fork() 一起使用
- 直接使用池实例
- API 文档 - 可用池实现
池
QueuePool
AsyncAdaptedQueuePool
SingletonThreadPool
AssertionPool
NullPool
StaticPool
ManagesConnection
ConnectionPoolEntry
PoolProxiedConnection
PoolProxiedConnection.close()
PoolProxiedConnection.dbapi_connection
PoolProxiedConnection.detach()
PoolProxiedConnection.driver_connection
PoolProxiedConnection.info
PoolProxiedConnection.invalidate()
PoolProxiedConnection.is_detached
PoolProxiedConnection.is_valid
PoolProxiedConnection.record_info
_ConnectionFairy
_ConnectionRecord
连接池¶
连接池是一种标准技术,用于在内存中维护长时间运行的连接以实现高效重用,并为应用程序可能同时使用的连接总数提供管理。
特别是对于服务器端 Web 应用程序,连接池是在内存中维护活动数据库连接“池”的标准方法,这些连接在请求之间重用。
SQLAlchemy 包括多个连接池实现,这些实现与 Engine
集成。 它们也可以直接用于希望将池添加到其他普通 DBAPI 方法的应用程序。
连接池配置¶
由 Engine
返回的 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()
默认使用大小为 5 的 QueuePool
而无需考虑应用程序是否真的需要排队 5 个连接是完全可以的 - 只有当应用程序实际并发使用 5 个连接时,池才会增长到该大小,在这种情况下,使用小池是完全合适的默认行为。
注意
QueuePool
类与 asyncio 不兼容。 当使用 create_async_engine
创建 AsyncEngine
实例时,将使用 AsyncAdaptedQueuePool
类,该类使用 asyncio 兼容的队列实现。
切换池实现¶
将不同类型的池与 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 连接。 此方法的返回值是包含在透明代理中的 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 驱动程序不支持此用法。
返回时重置¶
池包括“返回时重置”行为,当连接返回到池时,它将调用 DBAPI 连接的 rollback()
方法。 这是为了从连接中删除任何现有的事务状态,这不仅包括未提交的数据,还包括表和行锁。 对于大多数 DBAPI,调用 rollback()
的成本很低,如果 DBAPI 已经完成事务,则该方法应该是空操作。
为非事务连接禁用返回时重置¶
对于 rollback()
无用的非常特殊的情况,例如当使用为 自动提交 配置的连接或当使用没有 ACID 功能的数据库(例如 MySQL 的 MyISAM 引擎)时,可以禁用返回时重置行为,这通常是出于性能原因而完成的。 这可以通过使用 Pool.reset_on_return
参数 Pool
来实现,该参数也可从 create_engine()
获得,作为 create_engine.pool_reset_on_return
,传递值 None
。 下面的示例说明了这一点,结合了 create_engine.isolation_level
参数设置 AUTOCOMMIT
non_acid_engine = create_engine(
"mysql://scott:tiger@host/db",
pool_reset_on_return=None,
isolation_level="AUTOCOMMIT",
)
上面的引擎实际上不会在连接返回到池时执行 ROLLBACK; 由于启用了 AUTOCOMMIT,驱动程序也不会执行任何 BEGIN 操作。
自定义返回时重置方案¶
由单个 rollback()
组成的“返回时重置”可能不足以满足某些用例; 特别是,使用临时表的应用程序可能希望在连接检入时自动删除这些表。 某些(但并非全部)后端包含可以在数据库连接范围内“重置”此类表的功能,这可能是连接池重置的理想行为。 其他服务器资源(如预处理语句句柄和服务器端语句缓存)可能会在检入过程之后仍然存在,这可能是也可能不是理想的,具体取决于具体情况。 同样,某些(但同样并非全部)后端可能会提供重置此状态的方法。 已知具有此类重置方案的两个 SQLAlchemy 包含的方言包括 Microsoft SQL Server,其中经常使用未记录但广为人知的存储过程 sp_reset_connection
,以及 PostgreSQL,它有一系列完善的文档化命令,包括 DISCARD
RESET
, DEALLOCATE
, 和 UNLISTEN
。
以下示例说明了如何使用 PoolEvents.reset()
事件钩子,用 Microsoft SQL Server sp_reset_connection
存储过程替换返回时重置。 create_engine.pool_reset_on_return
参数设置为 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()
事件添加了其他状态参数,并额外确保为所有“重置”事件调用该事件,使其适合作为自定义“重置”处理程序的位置。 以前使用 PoolEvents.checkin()
处理程序的方案仍然可用。
另请参阅
连接池的临时表/资源重置 - 在 Microsoft SQL Server 文档中
连接池的临时表/资源重置 在 PostgreSQL 文档中
记录返回时重置事件¶
可以设置池事件(包括返回时重置)的日志记录 logging.DEBUG
日志级别以及 sqlalchemy.pool
记录器,或者在使用 create_engine()
时将 create_engine.echo_pool
设置为 "debug"
>>> from sqlalchemy import create_engine
>>> engine = create_engine("postgresql://scott:tiger@localhost/test", echo_pool="debug")
上面的池将显示详细日志记录,包括返回时重置
>>> 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
池事件¶
连接池支持事件接口,该接口允许在首次连接、每次新连接以及连接的检出和检入时执行钩子。 有关详细信息,请参阅 PoolEvents
。
处理断开连接¶
连接池能够刷新单个连接及其整个连接集,将先前池化的连接设置为“无效”。 常见的用例是允许连接池在数据库服务器重新启动并且所有先前建立的连接不再可用时优雅地恢复。 有两种方法可以解决这个问题。
断开连接处理 - 悲观¶
悲观方法是指在每次连接池检出开始时在 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”将尝试最多三次,然后放弃,传播最后收到的数据库错误。
至关重要的是要注意,pre-ping 方法 不适应在事务或其他 SQL 操作中间断开的连接。 如果数据库在事务进行中变得不可用,则事务将丢失并且将引发数据库错误。 虽然 Connection
对象将检测到“断开连接”情况,并回收连接以及使连接池的其余部分失效,但当发生这种情况时,引发异常的单个操作将丢失,并且由应用程序来决定放弃操作,或再次重试整个事务。 如果引擎配置为使用 DBAPI 级别的自动提交连接,如 设置事务隔离级别,包括 DBAPI 自动提交 中所述,则 可能 使用事件在操作中间透明地重新连接连接。 有关示例,请参阅 如何自动“重试”语句执行? 部分。
对于使用“SELECT 1”并捕获错误以检测断开连接的方言,可以使用 DialectEvents.handle_error()
钩子为新的后端特定错误消息增强断开连接测试。
自定义 / 遗留悲观 Ping¶
在添加 create_engine.pool_pre_ping
之前,“pre-ping”方法历史上是使用 ConnectionEvents.engine_connect()
引擎事件手动执行的。 最常见的配方如下,以供参考,以防应用程序已经在使用此类配方,或者需要特殊行为
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 连接,并且引发与“断开连接”事件对应的异常时,连接将失效。 然后 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 Session 的典型 Web 应用程序中,上述情况将对应于单个请求失败并出现 500 错误,然后 Web 应用程序在此之后继续正常运行。 因此,该方法是“乐观的”,因为不预期频繁的数据库重启。
设置池回收¶
可以增强“乐观”方法的附加设置是设置池回收参数。 此参数阻止池使用已超过特定时间段的特定连接,并且适用于数据库后端(如 MySQL),这些后端会自动关闭在特定时间段后已过期的连接
from sqlalchemy import create_engine
e = create_engine("mysql+mysqldb://scott:tiger@localhost/test", pool_recycle=3600)
上面,任何已打开超过一小时的 DBAPI 连接都将在下次检出时失效并替换。 请注意,失效 仅 在检出期间发生 - 而不是在任何处于检出状态的连接上。 pool_recycle
是 Pool
本身的功能,独立于是否正在使用 Engine
。
关于失效的更多信息¶
Pool
提供“连接失效”服务,该服务允许显式失效连接以及响应于确定连接不可用的条件自动失效连接。
“失效”意味着从池中删除并丢弃特定的 DBAPI 连接。 如果不清楚连接本身可能未关闭,则对此连接调用 .close()
方法,但是如果此方法失败,则记录异常,但操作仍会继续进行。
使用 Engine
时,Connection.invalidate()
方法是显式失效的常用入口点。DBAPI 连接可能失效的其他情况包括
DBAPI 异常,例如
OperationalError
,当调用诸如connection.execute()
之类的方法时引发,被检测为指示所谓的“断开连接”情况。由于 Python DBAPI 没有提供用于确定异常性质的标准系统,因此所有 SQLAlchemy 方言都包含一个名为is_disconnect()
的系统,该系统将检查异常对象的内容,包括字符串消息和其中包含的任何潜在错误代码,以确定此异常是否指示连接不再可用。如果是这种情况,则会调用_ConnectionFairy.invalidate()
方法,然后丢弃 DBAPI 连接。当连接返回到连接池,并且调用
connection.rollback()
或connection.commit()
方法(如连接池的“返回时重置”行为所规定)抛出异常时。将最后尝试调用连接上的.close()
,然后将其丢弃。当实现
PoolEvents.checkout()
的监听器引发DisconnectionError
异常时,指示连接将不可用,并且需要进行新的连接尝试。
所有发生的失效都将调用 PoolEvents.invalidate()
事件。
支持断开连接场景的新数据库错误代码¶
SQLAlchemy 方言各自包含一个名为 is_disconnect()
的例程,每当遇到 DBAPI 异常时都会调用该例程。DBAPI 异常对象会传递给此方法,其中特定于方言的启发式方法将确定收到的错误代码是否指示数据库连接已“断开连接”,或者处于其他不可用状态,表明应回收该连接。此处应用的启发式方法可以使用 DialectEvents.handle_error()
事件钩子进行自定义,该钩子通常通过拥有的 Engine
对象建立。使用此钩子,发生的所有错误都会传递一个名为 ExceptionContext
的上下文对象。自定义事件钩子可以控制是否应将特定错误视为“断开连接”情况,以及此断开连接是否应导致整个连接池失效。
例如,要添加支持以将 Oracle 数据库驱动程序错误代码 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 数据库错误调用,包括在使用 连接池预先 ping 功能时捕获的错误,这些后端依赖于断开连接错误处理(2.0 版本新增)。
使用 FIFO 与 LIFO¶
QueuePool
类具有一个名为 QueuePool.use_lifo
的标志,也可以通过 create_engine()
使用标志 create_engine.pool_use_lifo
访问。将此标志设置为 True
会使连接池的“队列”行为变为“堆栈”行为,例如,返回到连接池的最后一个连接是在下一个请求中第一个使用的连接。与连接池长期以来的先进先出行为(产生串行使用连接池中每个连接的循环效果)相反,LIFO 模式允许多余的连接在连接池中保持空闲状态,从而允许服务器端超时方案关闭这些连接。FIFO 和 LIFO 之间的区别基本上在于,即使在空闲期间,连接池是否需要保持一组完整的连接准备就绪
engine = create_engine("postgresql://", pool_use_lifo=True, pool_pre_ping=True)
在上面,我们还使用了 create_engine.pool_pre_ping
标志,以便从服务器端关闭的连接可以由连接池优雅地处理,并替换为新连接。
请注意,该标志仅适用于 QueuePool
的使用。
1.3 版本新增。
另请参阅
将连接池与多进程或 os.fork() 一起使用¶
至关重要的是,当使用连接池时,以及扩展到使用通过 create_engine()
创建的 Engine
时,不要将池化连接共享到 fork 进程。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
的Engine.dispose.close
参数。这样做是为了使新进程不会触及任何父进程的连接,而是从新连接开始。这是推荐的方法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
对象。
直接使用连接池实例¶
可以在没有引擎的情况下直接使用连接池实现。这可以用于只想使用连接池行为而无需所有其他 SQLAlchemy 功能的应用程序中。在下面的示例中,使用 create_pool_from_url()
获取 MySQLdb
方言的默认连接池
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 文档 - 可用的连接池实现¶
对象名称 | 描述 |
---|---|
代理 DBAPI 连接并提供取消引用时返回支持。 |
|
维护连接池中的位置,该位置引用池化连接。 |
|
一个 |
|
|
|
用于维护代表 |
|
两个连接管理接口 |
|
一个不池化连接的连接池。 |
|
连接池的抽象基类。 |
|
一个 |
|
一个为每个线程维护一个连接的连接池。 |
|
一个只有一个连接的连接池,用于所有请求。 |
- class sqlalchemy.pool.Pool¶
连接池的抽象基类。
类签名
class
sqlalchemy.pool.Pool
(sqlalchemy.log.Identified
,sqlalchemy.event.registry.EventTarget
)-
method
sqlalchemy.pool.Pool.
__init__(creator: _CreatorFnType | _CreatorWRecFnType, recycle: int = -1, echo: log._EchoFlagType = None, logging_name: str | None = None, reset_on_return: _ResetStyleArgType = True, events: List[Tuple[_ListenerFnType, str]] | None = None, dialect: _ConnDialect | Dialect | None = None, pre_ping: bool = False, _dispatch: _DispatchCommon[Pool] | None = None)¶ 构造一个连接池。
- 参数:
creator¶ – 一个可调用函数,它返回一个 DB-API 连接对象。该函数将在调用时带参数。
recycle¶ – 如果设置为 -1 以外的值,则为连接回收之间的时间秒数,这意味着在检出时,如果超过此超时时间,连接将被关闭并替换为新打开的连接。默认为 -1。
logging_name¶ – 字符串标识符,将用于 “sqlalchemy.pool” 日志记录器中生成的日志记录的 “name” 字段中。默认为对象 ID 的十六进制字符串。
echo¶ –
如果为 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” 更危险,因为事务中存在的任何数据更改都将被无条件提交。None
- 不对连接执行任何操作。如果数据库/DBAPI 始终以纯 “自动提交” 模式工作,或者如果使用PoolEvents.reset()
事件处理程序建立自定义重置处理程序,则此设置可能适用。True
- 与 “rollback” 相同,此处是为了向后兼容。False
- 与 None 相同,此处是为了向后兼容。
为了进一步自定义返回时重置,可以使用
PoolEvents.reset()
事件钩子,该钩子可以在重置时执行任何所需的连接活动。events¶ – 一个 2 元组列表,每个元组的形式为
(callable, target)
,将在构造时传递给listen()
。此处提供是为了可以在应用方言级别的监听器之前,通过create_engine()
分配事件监听器。dialect¶ – 一个
Dialect
,它将处理在 DBAPI 连接上调用 rollback()、close() 或 commit() 的工作。如果省略,则使用内置的 “stub” 方言。使用create_engine()
的应用程序不应使用此参数,因为它由引擎创建策略处理。pre_ping¶ –
如果为 True,则连接池将在检出时在连接上发出 “ping”(通常为 “SELECT 1”,但特定于方言),以测试连接是否处于活动状态。如果不是,则连接将被透明地重新连接,并且成功后,在该时间戳之前建立的所有其他池化连接都将失效。需要也传递一个方言来解释断开连接错误。
1.2 版本新增。
-
method
sqlalchemy.pool.Pool.
connect() → PoolProxiedConnection¶ 从连接池返回一个 DBAPI 连接。
该连接经过工具化,以便在其
close()
方法被调用时,连接将返回到连接池。
-
method
sqlalchemy.pool.Pool.
dispose() → None¶ 处置此连接池。
此方法保留了检出的连接保持打开的可能性,因为它仅影响连接池中空闲的连接。
另请参阅
-
method
sqlalchemy.pool.Pool.
recreate() → Pool¶ 返回一个新的
Pool
,与当前的连接池类相同,并使用相同的创建参数进行配置。
-
method
sqlalchemy.pool.Pool.
status() → str¶ 返回此连接池状态的简要描述。
-
method
- class sqlalchemy.pool.QueuePool¶
一个
Pool
,它对打开的连接数施加限制。QueuePool
是用于所有Engine
对象的默认连接池实现,SQLite 和:memory:
数据库除外。QueuePool
类与 asyncio 和create_async_engine()
不兼容。当使用create_async_engine()
且未指定其他类型的连接池时,将自动使用AsyncAdaptedQueuePool
类。类签名
-
method
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¶ – 连接池的最大溢出大小。当检出连接数达到 pool_size 中设置的大小后,将返回额外的连接,直到此限制。当这些额外的连接返回到连接池时,它们将被断开连接并丢弃。由此可见,连接池将允许的同时连接总数为 pool_size + max_overflow,连接池将允许的“休眠”连接总数为 pool_size。max_overflow 可以设置为 -1 以表示没有溢出限制;对并发连接的总数没有限制。默认为 10。
timeout¶ – 在放弃返回连接之前等待的秒数。默认为 30.0。这可以是浮点数,但受 Python 时间函数的限制,这些函数在数十毫秒内可能不可靠。
use_lifo¶ –
在检索连接时使用 LIFO(后进先出)而不是 FIFO(先进先出)。使用 LIFO,服务器端超时方案可以减少非高峰使用期间使用的连接数。在规划服务器端超时时,请确保使用回收或预 ping 策略来优雅地处理过时的连接。
1.3 版本新增。
**kw¶ – 其他关键字参数,包括
Pool.recycle
、Pool.echo
、Pool.reset_on_return
等,都将传递给Pool
构造函数。
-
method
sqlalchemy.pool.QueuePool.
dispose() → None¶ 处置此连接池。
此方法保留了检出的连接保持打开的可能性,因为它仅影响连接池中空闲的连接。
另请参阅
-
method
sqlalchemy.pool.QueuePool.
recreate() → QueuePool¶ 返回一个新的
Pool
,与当前的连接池类相同,并使用相同的创建参数进行配置。
-
method
sqlalchemy.pool.QueuePool.
status() → str¶ 返回此连接池状态的简要描述。
-
method
- class sqlalchemy.pool.AsyncAdaptedQueuePool¶
QueuePool
的 asyncio 兼容版本。当使用从
create_async_engine()
生成的AsyncEngine
引擎时,默认使用此连接池。它使用与 asyncio 兼容的队列实现,该实现不使用threading.Lock
。AsyncAdaptedQueuePool
的参数和操作与其他方面与QueuePool
相同。
- class sqlalchemy.pool.SingletonThreadPool¶
一个为每个线程维护一个连接的连接池。
为每个线程维护一个连接,永远不会将连接移动到创建它的线程之外的其他线程。
警告
SingletonThreadPool
将对超出pool_size
设置大小之外的任意连接调用.close()
,例如,如果使用的唯一 线程标识 多于pool_size
声明的数量。此清理是非确定性的,并且对链接到这些线程标识的连接当前是否正在使用不敏感。SingletonThreadPool
可能会在未来的版本中得到改进,但在其当前状态下,它通常仅用于使用 SQLite:memory:
数据库的测试场景,不建议用于生产环境。SingletonThreadPool
类与 asyncio 和create_async_engine()
不兼容。选项与
Pool
的选项相同,以及- 参数:
pool_size¶ – 一次维护连接的线程数。默认为 5。
当使用基于内存的数据库时,SQLite 方言会自动使用
SingletonThreadPool
。请参阅 SQLite。成员
-
method
sqlalchemy.pool.SingletonThreadPool.
connect() → PoolProxiedConnection¶ 从连接池返回一个 DBAPI 连接。
该连接经过工具化,以便在其
close()
方法被调用时,连接将返回到连接池。
-
method
sqlalchemy.pool.SingletonThreadPool.
dispose() → None¶ 处置此连接池。
-
method
sqlalchemy.pool.SingletonThreadPool.
recreate() → SingletonThreadPool¶ 返回一个新的
Pool
,与当前的连接池类相同,并使用相同的创建参数进行配置。
-
method
sqlalchemy.pool.SingletonThreadPool.
status() → str¶ 返回此连接池状态的简要描述。
- class sqlalchemy.pool.AssertionPool¶
一个
Pool
,它在任何给定时间最多允许一个检出的连接。如果在一次检出多个连接,这将引发异常。对于调试正在使用超出预期连接数的代码很有用。
AssertionPool
类与 asyncio 和create_async_engine()
兼容。成员
-
method
sqlalchemy.pool.AssertionPool.
dispose() → None¶ 处置此连接池。
此方法保留了检出的连接保持打开的可能性,因为它仅影响连接池中空闲的连接。
另请参阅
-
method
sqlalchemy.pool.AssertionPool.
recreate() → AssertionPool¶ 返回一个新的
Pool
,与当前的连接池类相同,并使用相同的创建参数进行配置。
-
method
sqlalchemy.pool.AssertionPool.
status() → str¶ 返回此连接池状态的简要描述。
-
method
- class sqlalchemy.pool.NullPool¶
一个不池化连接的连接池。
相反,它字面上为每个连接的打开/关闭操作打开和关闭底层 DB-API 连接。
此连接池实现不支持与重新连接相关的功能,例如
recycle
和连接失效,因为没有持久持有连接。NullPool
类与 asyncio 和create_async_engine()
兼容。成员
类签名
-
method
sqlalchemy.pool.NullPool.
dispose() → None¶ 处置此连接池。
此方法保留了检出的连接保持打开的可能性,因为它仅影响连接池中空闲的连接。
另请参阅
-
method
sqlalchemy.pool.NullPool.
recreate() → NullPool¶ 返回一个新的
Pool
,与当前的连接池类相同,并使用相同的创建参数进行配置。
-
method
sqlalchemy.pool.NullPool.
status() → str¶ 返回此连接池状态的简要描述。
-
method
- class sqlalchemy.pool.StaticPool¶
一个只有一个连接的连接池,用于所有请求。
与重新连接相关的功能(例如
recycle
和连接失效(也用于支持自动重新连接))目前仅部分支持,可能不会产生好的结果。StaticPool
类与 asyncio 和create_async_engine()
兼容。成员
类签名
class
sqlalchemy.pool.StaticPool
(sqlalchemy.pool.base.Pool
)-
method
sqlalchemy.pool.StaticPool.
dispose() → None¶ 处置此连接池。
此方法保留了检出的连接保持打开的可能性,因为它仅影响连接池中空闲的连接。
另请参阅
-
method
sqlalchemy.pool.StaticPool.
recreate() → StaticPool¶ 返回一个新的
Pool
,与当前的连接池类相同,并使用相同的创建参数进行配置。
-
method
sqlalchemy.pool.StaticPool.
status() → str¶ 返回此连接池状态的简要描述。
-
method
- class sqlalchemy.pool.ManagesConnection¶
两个连接管理接口
PoolProxiedConnection
和ConnectionPoolEntry
的公共基类。这两个对象通常通过连接池事件钩子在面向公众的 API 中公开,文档记录在
PoolEvents
中。2.0 版本新增。
-
attribute
sqlalchemy.pool.ManagesConnection.
dbapi_connection: DBAPIConnection | None¶ 对正在跟踪的实际 DBAPI 连接的引用。
这是一个 PEP 249 兼容对象,对于传统的同步风格方言,它由正在使用的第三方 DBAPI 实现提供。对于 asyncio 方言,该实现通常是由 SQLAlchemy 方言本身提供的适配器对象;底层 asyncio 对象可通过
ManagesConnection.driver_connection
属性获得。SQLAlchemy 的 DBAPI 连接接口基于
DBAPIConnection
协议对象
-
attribute
sqlalchemy.pool.ManagesConnection.
driver_connection: Any | None¶ Python DBAPI 或数据库驱动程序使用的“驱动程序级别”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将与
ManagesConnection.dbapi_connection
的对象相同。对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终“连接”对象,例如asyncpg.Connection
对象,它将没有标准的 pep-249 方法。1.4.24 版本新增。
-
attribute
sqlalchemy.pool.ManagesConnection.
info¶ 与此
ManagesConnection
实例引用的底层 DBAPI 连接关联的信息字典,允许用户定义的数据与连接关联。此字典中的数据在 DBAPI 连接本身的生命周期内是持久的,包括跨连接池检入和检出。当连接失效并替换为新连接时,此字典将被清除。
对于未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它是分离的),则该属性返回一个字典,该字典是ConnectionPoolEntry
本地的。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
-
method
sqlalchemy.pool.ManagesConnection.
invalidate(e: BaseException | None = None, soft: bool = False) → None¶ 将托管连接标记为无效。
另请参阅
-
attribute
sqlalchemy.pool.ManagesConnection.
record_info¶ 与此
ManagesConnection
关联的持久信息字典。与
ManagesConnection.info
字典不同,此字典的生命周期是拥有它的ConnectionPoolEntry
的生命周期;因此,对于连接池中的特定条目,此字典将在重新连接和连接失效之间持续存在。对于一个未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它是分离的),此属性返回 None。 与从不为 None 的ManagesConnection.info
字典相比,情况则不同。
-
attribute
- class sqlalchemy.pool.ConnectionPoolEntry¶
用于维护代表
Pool
实例的单个数据库连接的对象的接口。ConnectionPoolEntry
对象代表连接池中特定连接的长期维护,包括使该连接过期或失效,以便用新连接替换它,而新连接将继续由同一个ConnectionPoolEntry
实例维护。 与PoolProxiedConnection
(它是短期的、每次检出的连接管理器)相比,此对象在连接池中特定“槽位”的生命周期内持续存在。ConnectionPoolEntry
对象主要在连接池事件钩子(例如PoolEvents.connect()
和PoolEvents.checkout()
)传递时对面向公众的 API 代码可见。2.0 版本新增:
ConnectionPoolEntry
为内部类_ConnectionRecord
提供了面向公众的接口。-
method
sqlalchemy.pool.ConnectionPoolEntry.
close() → None¶ 关闭由此连接池条目管理的 DBAPI 连接。
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
dbapi_connection: DBAPIConnection | None¶ 对正在跟踪的实际 DBAPI 连接的引用。
这是一个 PEP 249 兼容对象,对于传统的同步风格方言,它由正在使用的第三方 DBAPI 实现提供。 对于 asyncio 方言,该实现通常是由 SQLAlchemy 方言本身提供的适配器对象; 底层 asyncio 对象可通过
ManagesConnection.driver_connection
属性获得。SQLAlchemy 的 DBAPI 连接接口基于
DBAPIConnection
协议对象
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
driver_connection: Any | None¶ Python DBAPI 或数据库驱动程序使用的“驱动程序级别”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将与
ManagesConnection.dbapi_connection
的对象相同。 对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终“连接”对象,例如asyncpg.Connection
对象,它不具有标准的 pep-249 方法。1.4.24 版本新增。
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
in_use¶ 如果连接当前已检出,则返回 True
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
info¶ 继承自
ManagesConnection
的ManagesConnection.info
属性与此
ManagesConnection
实例引用的底层 DBAPI 连接关联的信息字典,允许用户定义的数据与连接关联。此字典中的数据在 DBAPI 连接本身的生命周期内是持久的,包括跨连接池检入和检出。当连接失效并替换为新连接时,此字典将被清除。
对于未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它是分离的),则该属性返回一个字典,该字典是ConnectionPoolEntry
本地的。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
-
method
sqlalchemy.pool.ConnectionPoolEntry.
invalidate(e: BaseException | None = None, soft: bool = False) → None¶ 继承自
ManagesConnection
的ManagesConnection.invalidate()
方法将托管连接标记为无效。
另请参阅
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
record_info¶ 继承自
ManagesConnection
的ManagesConnection.record_info
属性与此
ManagesConnection
关联的持久信息字典。与
ManagesConnection.info
字典不同,此字典的生命周期是拥有它的ConnectionPoolEntry
的生命周期;因此,对于连接池中的特定条目,此字典将在重新连接和连接失效之间持续存在。对于一个未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它是分离的),此属性返回 None。 与从不为 None 的ManagesConnection.info
字典相比,情况则不同。
-
method
- class 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
-
method
sqlalchemy.pool.PoolProxiedConnection.
close() → None¶ 将此连接释放回连接池。
PoolProxiedConnection.close()
方法遮蔽了 PEP 249.close()
方法,更改了其行为,使其变为将代理连接 释放 回连接池。在释放回连接池后,连接是保持“打开”状态并池化在 Python 进程中,还是实际关闭并从 Python 进程中移除,取决于正在使用的连接池实现及其配置和当前状态。
-
attribute
sqlalchemy.pool.PoolProxiedConnection.
dbapi_connection: DBAPIConnection | None¶ 对正在跟踪的实际 DBAPI 连接的引用。
这是一个 PEP 249 兼容对象,对于传统的同步风格方言,它由正在使用的第三方 DBAPI 实现提供。 对于 asyncio 方言,该实现通常是由 SQLAlchemy 方言本身提供的适配器对象; 底层 asyncio 对象可通过
ManagesConnection.driver_connection
属性获得。SQLAlchemy 的 DBAPI 连接接口基于
DBAPIConnection
协议对象
-
method
sqlalchemy.pool.PoolProxiedConnection.
detach() → None¶ 将此连接与其连接池分离。
这意味着连接在关闭时将不再返回到连接池,而是会被直接关闭。 关联的
ConnectionPoolEntry
将与此 DBAPI 连接解除关联。请注意,在分离后,连接池实现施加的任何总体连接限制约束都可能被违反,因为分离的连接已从连接池的知识和控制中移除。
-
attribute
sqlalchemy.pool.PoolProxiedConnection.
driver_connection: Any | None¶ Python DBAPI 或数据库驱动程序使用的“驱动程序级别”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将与
ManagesConnection.dbapi_connection
的对象相同。 对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终“连接”对象,例如asyncpg.Connection
对象,它不具有标准的 pep-249 方法。1.4.24 版本新增。
-
attribute
sqlalchemy.pool.PoolProxiedConnection.
info¶ 继承自
ManagesConnection
的ManagesConnection.info
属性与此
ManagesConnection
实例引用的底层 DBAPI 连接关联的信息字典,允许用户定义的数据与连接关联。此字典中的数据在 DBAPI 连接本身的生命周期内是持久的,包括跨连接池检入和检出。当连接失效并替换为新连接时,此字典将被清除。
对于未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它是分离的),则该属性返回一个字典,该字典是ConnectionPoolEntry
本地的。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
-
method
sqlalchemy.pool.PoolProxiedConnection.
invalidate(e: BaseException | None = None, soft: bool = False) → None¶ 继承自
ManagesConnection
的ManagesConnection.invalidate()
方法将托管连接标记为无效。
另请参阅
-
attribute
sqlalchemy.pool.PoolProxiedConnection.
is_detached¶ 如果此
PoolProxiedConnection
与其连接池分离,则返回 True。
-
attribute
sqlalchemy.pool.PoolProxiedConnection.
is_valid¶ 如果此
PoolProxiedConnection
仍然引用活动的 DBAPI 连接,则返回 True。
-
attribute
sqlalchemy.pool.PoolProxiedConnection.
record_info¶ 继承自
ManagesConnection
的ManagesConnection.record_info
属性与此
ManagesConnection
关联的持久信息字典。与
ManagesConnection.info
字典不同,此字典的生命周期是拥有它的ConnectionPoolEntry
的生命周期;因此,对于连接池中的特定条目,此字典将在重新连接和连接失效之间持续存在。对于一个未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例(例如,如果它是分离的),此属性返回 None。 与从不为 None 的ManagesConnection.info
字典相比,情况则不同。
-
method
- class sqlalchemy.pool._ConnectionFairy¶
代理 DBAPI 连接并提供取消引用时返回支持。
这是
Pool
实现使用的内部对象,用于为该Pool
传递的 DBAPI 连接提供上下文管理。 此类的面向公众的接口由PoolProxiedConnection
类描述。 有关公共 API 详细信息,请参阅该类。名称 “fairy” 的灵感来自于
_ConnectionFairy
对象的生命周期是短暂的,因为它仅持续从连接池检出的特定 DBAPI 连接的长度,此外,作为透明代理,它在很大程度上是不可见的。类签名
class
sqlalchemy.pool._ConnectionFairy
(sqlalchemy.pool.base.PoolProxiedConnection
)
- class sqlalchemy.pool._ConnectionRecord¶
维护连接池中的位置,该位置引用池化连接。
这是
Pool
实现使用的内部对象,用于为该Pool
维护的 DBAPI 连接提供上下文管理。 此类的面向公众的接口由ConnectionPoolEntry
类描述。 有关公共 API 详细信息,请参阅该类。类签名
class
sqlalchemy.pool._ConnectionRecord
(sqlalchemy.pool.base.ConnectionPoolEntry
)
flambé! 龙和 The Alchemist 图像设计由 Rotem Yaari 创作并慷慨捐赠。
使用 Sphinx 7.2.6 创建。 文档最后生成时间:Tue 11 Mar 2025 02:40:17 PM EDT