SqlAlchemy 2.0 中文文档(四十四)(3)https://developer.aliyun.com/article/1563070
另请参阅
Engine.execution_options()
Executable.execution_options()
Connection.get_execution_options()
ORM 执行选项 - 所有 ORM 特定执行选项的文档
method get_execution_options() → _ExecuteOptions
获取在执行期间生效的非 SQL 选项。
版本 1.3 中的新内容。
另请参阅
Connection.execution_options()
method get_isolation_level() → Literal['SERIALIZABLE', 'REPEATABLE READ', 'READ COMMITTED', 'READ UNCOMMITTED', 'AUTOCOMMIT']
返回此连接范围内存在于数据库中的当前实际隔离级别。
此属性将执行与数据库的实时 SQL 操作,以获取当前隔离级别,因此返回的值是底层 DBAPI 连接上的实际级别,而不管此状态如何设置。这将是四个实际隔离模式之一 READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
、SERIALIZABLE
。它不包括 AUTOCOMMIT
隔离级别设置。第三方方言也可能具有额外的隔离级别设置。
注
此方法不会报告 AUTOCOMMIT 隔离级别,该级别是独立于实际隔离级别的 dbapi 设置。当使用 AUTOCOMMIT 时,数据库连接仍然具有正在使用的“传统”隔离模式,通常是四个值之一 READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
、SERIALIZABLE
。
与返回初始连接时数据库上存在的隔离级别的 Connection.default_isolation_level
访问器进行比较。
另请参阅
Connection.default_isolation_level
- 查看默认级别
create_engine.isolation_level
- 设置每个Engine
的隔离级别
Connection.execution_options.isolation_level
- 设置每个Connection
的隔离级别
method get_nested_transaction() → NestedTransaction | None
返回当前正在进行的嵌套事务(如果有)。
版本 1.4 中的新功能。
method get_transaction() → RootTransaction | None
返回当前正在进行的根事务(如果有)。
版本 1.4 中的新功能。
method in_nested_transaction() → bool
如果事务正在进行中,则返回 True。
method in_transaction() → bool
如果事务正在进行中,则返回 True。
attribute info
与由此Connection
引用的底层 DBAPI 连接相关联的信息字典,允许将用户定义的数据与连接关联起来。
这里的数据将随着 DBAPI 连接一起,包括在将其返回到连接池并在后续的Connection
实例中再次使用时。
method invalidate(exception: BaseException | None = None) → None
使与这个Connection
关联的底层 DBAPI 连接无效。
将立即尝试关闭底层的 DBAPI 连接;但是,如果此操作失败,则会记录错误但不会引发错误。无论 close()是否成功,连接都将被丢弃。
在下一次使用时(“使用”通常意味着使用Connection.execute()
方法或类似方法),这个Connection
将尝试使用Pool
的服务来获取一个新的 DBAPI 连接作为连接源(例如“重新连接”)。
如果在调用Connection.invalidate()
方法时正在进行事务(例如已调用Connection.begin()
方法),则在 DBAPI 级别上,与此事务关联的所有状态都会丢失,因为 DBAPI 连接已关闭。在调用Transaction.rollback()
方法结束Transaction
对象之前,Connection
不会允许重新连接;在那之前,任何继续使用Connection
的尝试都将引发InvalidRequestError
。这是为了防止应用程序在事务由于失效而丢失的情况下意外继续进行事务操作。
Connection.invalidate()
方法,就像自动失效一样,将在连接池级别调用PoolEvents.invalidate()
事件。
参数:
exception – 可选的Exception
实例,表示失效的原因,将传递给事件处理程序和日志记录函数。
另请参阅
更多关于失效的信息
attribute invalidated
如果此连接已失效,则返回 True。
这并不表示连接是否在池级别被失效。
method rollback() → None
回滚当前正在进行的事务。
如果已经启动了事务,则此方法会回滚当前事务。如果没有启动事务,则此方法不起作用。如果已启动事务且连接处于失效状态,则使用此方法清除事务。
每当首次执行语句或调用Connection.begin()
方法时,将自动在Connection
上启动事务。
注意
Connection.rollback()
方法仅作用于与Connection
对象关联的主数据库事务。它不会操作从Connection.begin_nested()
方法调用的 SAVEPOINT;要控制 SAVEPOINT,请在Connection.begin_nested()
方法本身返回的NestedTransaction
上调用NestedTransaction.rollback()
。
method scalar(statement: Executable, parameters: _CoreSingleExecuteParams | None = None, *, execution_options: CoreExecuteOptionsParameter | None = None) → Any
执行 SQL 语句构造并返回标量对象。
此方法是在调用Connection.execute()
方法后调用Result.scalar()
方法的简写。参数是相等的。
返回:
表示返回的第一行的第一列的标量 Python 值。
method scalars(statement: Executable, parameters: _CoreAnyExecuteParams | None = None, *, execution_options: CoreExecuteOptionsParameter | None = None) → ScalarResult[Any]
执行并返回标量结果集,该结果集从每行的第一列中产生标量值。
此方法相当于调用Connection.execute()
以接收Result
对象,然后调用Result.scalars()
方法生成ScalarResult
实例。
返回:
一个ScalarResult
在版本 1.4.24 中新增。
method schema_for_object(obj: HasSchemaAttr) → str | None
返回给定架构项的架构名称,考虑到当前架构翻译映射。
class sqlalchemy.engine.CreateEnginePlugin
一组旨在根据 URL 中的入口点名称增强Engine
对象构建的钩子集。
CreateEnginePlugin
的目的是允许第三方系统应用引擎、池和方言级事件侦听器,而无需修改目标应用程序;相反,插件名称可以添加到数据库 URL。CreateEnginePlugin
的目标应用程序包括:
- 连接和 SQL 性能工具,例如使用事件来跟踪检查次数和/或语句所花费的时间
- 连接插件和 SQL 性能工具,例如代理
一个简陋的将日志记录器附加到Engine
对象的CreateEnginePlugin
可能如下所示:
import logging from sqlalchemy.engine import CreateEnginePlugin from sqlalchemy import event class LogCursorEventsPlugin(CreateEnginePlugin): def __init__(self, url, kwargs): # consume the parameter "log_cursor_logging_name" from the # URL query logging_name = url.query.get("log_cursor_logging_name", "log_cursor") self.log = logging.getLogger(logging_name) def update_url(self, url): "update the URL to one that no longer includes our parameters" return url.difference_update_query(["log_cursor_logging_name"]) def engine_created(self, engine): "attach an event listener after the new Engine is constructed" event.listen(engine, "before_cursor_execute", self._log_event) def _log_event( self, conn, cursor, statement, parameters, context, executemany): self.log.info("Plugin logged cursor event: %s", statement)
插件的注册方式与方言类似,都是使用入口点:
entry_points={ 'sqlalchemy.plugins': [ 'log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin' ]
使用上述名称的插件将从数据库 URL 中调用,如下所示:
from sqlalchemy import create_engine engine = create_engine( "mysql+pymysql://scott:tiger@localhost/test?" "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger" )
plugin
URL 参数支持多个实例,因此 URL 可以指定多个插件;它们按照 URL 中指定的顺序加载:
engine = create_engine( "mysql+pymysql://scott:tiger@localhost/test?" "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three")
插件名称也可以直接通过create_engine()
使用 create_engine.plugins
参数传递:
engine = create_engine( "mysql+pymysql://scott:tiger@localhost/test", plugins=["myplugin"])
从版本 1.2.3 开始新增功能:插件名称也以作为列表指定给create_engine()
。
插件可能会从URL
对象以及kwargs
字典中获取特定于插件的参数,该字典是传递给 create_engine()
调用的参数字典。"消耗"这些参数包括,它们在插件初始化时必须被移除,以便不将参数传递给 Dialect
构造函数,否则它们将引发 ArgumentError
,因为方言不知道它们。
自 SQLAlchemy 版本 1.4 起,应继续直接从kwargs
字典中消耗参数,通过诸如 dict.pop
的方法删除值。应通过实现 CreateEnginePlugin.update_url()
方法来消耗来自 URL
对象的参数,返回一个去除了特定于插件的参数的新 URL
副本:
class MyPlugin(CreateEnginePlugin): def __init__(self, url, kwargs): self.my_argument_one = url.query['my_argument_one'] self.my_argument_two = url.query['my_argument_two'] self.my_argument_three = kwargs.pop('my_argument_three', None) def update_url(self, url): return url.difference_update_query( ["my_argument_one", "my_argument_two"] )
像上面所示的参数将被从create_engine()
调用中消耗掉,例如:
from sqlalchemy import create_engine engine = create_engine( "mysql+pymysql://scott:tiger@localhost/test?" "plugin=myplugin&my_argument_one=foo&my_argument_two=bar", my_argument_three='bat' )
从版本 1.4 开始变更:URL
对象现在是不可变的;一个需要修改 URL
的 CreateEnginePlugin
应该实现新添加的 CreateEnginePlugin.update_url()
方法,在构造插件后调用该方法。
对于迁移,以以下方式构造插件,检查CreateEnginePlugin.update_url()
方法的存在以检测运行的版本:
class MyPlugin(CreateEnginePlugin): def __init__(self, url, kwargs): if hasattr(CreateEnginePlugin, "update_url"): # detect the 1.4 API self.my_argument_one = url.query['my_argument_one'] self.my_argument_two = url.query['my_argument_two'] else: # detect the 1.3 and earlier API - mutate the # URL directly self.my_argument_one = url.query.pop('my_argument_one') self.my_argument_two = url.query.pop('my_argument_two') self.my_argument_three = kwargs.pop('my_argument_three', None) def update_url(self, url): # this method is only called in the 1.4 version return url.difference_update_query( ["my_argument_one", "my_argument_two"] )
另请参阅
URL 对象现在是不可变的 - 对URL
变更的概述,其中还包括有关CreateEnginePlugin
的说明。
成员
init(), engine_created(), handle_dialect_kwargs(), handle_pool_kwargs(), update_url()
当引擎创建过程完成并产生Engine
对象时,它会再次通过CreateEnginePlugin.engine_created()
钩子传递给插件。在此钩子中,可以对引擎进行其他更改,通常涉及事件的设置(例如在 Core Events 中定义的事件)。
method __init__(url: URL, kwargs: Dict[str, Any])
构造一个新的CreateEnginePlugin
。
对于每次调用create_engine()
,都会单独实例化插件对象。一个单独的Engine
将传递给相应的此 URL 的CreateEnginePlugin.engine_created()
方法。
参数:
url
–URL
对象。插件可以检查URL
以获取参数。插件使用的参数应通过从CreateEnginePlugin.update_url()
方法返回的更新后的URL
来删除。
1.4 版更改:URL
对象现在是不可变的,因此需要更改URL
对象的CreateEnginePlugin
应实现CreateEnginePlugin.update_url()
方法。kwargs
– 传递给create_engine()
的关键字参数。
method engine_created(engine: Engine) → None
在完全构造时接收 Engine
对象。
插件可能会对引擎进行额外的更改,例如注册引擎或连接池事件。
method handle_dialect_kwargs(dialect_cls: Type[Dialect], dialect_args: Dict[str, Any]) → None
解析和修改方言关键字参数
method handle_pool_kwargs(pool_cls: Type[Pool], pool_args: Dict[str, Any]) → None
解析和修改池关键字参数
method update_url(url: URL) → URL
更新 URL
。
应返回一个新的 URL
。通常使用此方法来消耗从 URL
中的配置参数,必须删除这些参数,因为方言不会识别它们。URL.difference_update_query()
方法可用于删除这些参数。有关示例,请参见 CreateEnginePlugin
的文档字符串。
版本 1.4 中的新功能。
class sqlalchemy.engine.Engine
将 Pool
和 Dialect
连接起来,以提供数据库连接和行为的源。
通过 create_engine()
函数公开实例化一个 Engine
对象。
另请参阅
引擎配置
与引擎和连接一起工作
成员
begin(), clear_compiled_cache(), connect(), dispose(), driver, engine, execution_options(), get_execution_options(), name, raw_connection(), update_execution_options()
类签名
类 sqlalchemy.engine.Engine
(sqlalchemy.engine.interfaces.ConnectionEventsTarget
, sqlalchemy.log.Identified
, sqlalchemy.inspection.Inspectable
)
method begin() → Iterator[Connection]
返回一个上下文管理器,提供一个已建立的 Connection
和 Transaction
。
例如:
with engine.begin() as conn: conn.execute( text("insert into table (x, y, z) values (1, 2, 3)") ) conn.execute(text("my_special_procedure(5)"))
操作成功后,Transaction
将被提交。如果发生错误,则 Transaction
将被回滚。
另请参见
Engine.connect()
- 从 Engine
中获取 Connection
。
Connection.begin()
- 为特定的 Connection
开始一个 Transaction
。
method clear_compiled_cache() → None
清除与方言相关联的编译缓存。
这仅适用于通过 create_engine.query_cache_size
参数建立的内置缓存。它不会影响通过 Connection.execution_options.compiled_cache
参数传递的任何字典缓存。
版本 1.4
中的新功能。
method connect() → Connection
返回一个新的 Connection
对象。
Connection
作为 Python 上下文管理器,因此该方法的典型用法如下:
with engine.connect() as connection: connection.execute(text("insert into table values ('foo')")) connection.commit()
在上述代码块完成后,连接被“关闭”,其底层 DBAPI 资源被返回到连接池。这也会导致回滚任何明确启动的事务或通过 autobegin 启动的事务,并且如果已经开始并且仍在进行中,则会发出 ConnectionEvents.rollback()
事件。
另请参见
Engine.begin()
method dispose(close: bool = True) → None
处理此 Engine
使用的连接池。
在旧连接池被处理后立即创建一个新的连接池。之前的连接池会被主动处理,通过关闭该池中当前所有已签入的连接,或者被动处理,即失去对其的引用,但不关闭任何连接。后一种策略更适用于 forked Python 进程中的初始化程序。
参数:
close –
如果保留在其默认值 True
,则会完全关闭所有当前检入的数据库连接。仍然检出的连接将不会被关闭,但它们将不再与此 Engine
关联,因此当它们逐个关闭时,它们将与之关联的Pool
最终将被垃圾收集,如果尚未在检入时关闭,则将完全关闭。
如果设置为 False
,则先前的连接池将被取消引用,否则不会以任何方式触及。
版本 1.4.33 中的新增功能:添加了Engine.dispose.close
参数,以允许在子进程中替换连接池而不干扰父进程使用的连接。
请参阅
引擎处理
在多进程或 os.fork() 中使用连接池
attribute driver
此 Engine
使用的 Dialect
的驱动程序名称。
attribute engine
返回此 Engine
。
用于接受同一变量中的 Connection
/ Engine
对象的旧方案。
method execution_options(**opt: Any) → OptionEngine
返回一个新的Engine
,它将提供具有给定执行选项的Connection
对象。
返回的Engine
与原始Engine
相关联,因为它共享相同的连接池和其他状态:
- 新
Engine
使用的Pool
是同一实例。Engine.dispose()
方法将替换父引擎的连接池实例以及此引擎的连接池实例。 - 事件监听器是“级联”的 - 意思是,新的
Engine
继承了父级的事件,并且新事件可以单独与新的Engine
相关联。 - 日志配置和日志名称是从父
Engine
复制的。
Engine.execution_options()
方法的目的是实现多个Engine
对象引用相同连接池的方案,但是通过影响每个引擎的一些执行级别行为的选项进行区分。其中一个示例是将其分成单独的“读取器”和“写入器”Engine
实例,其中一个Engine
配置了较低的隔离级别设置,甚至使用“autocommit”禁用事务。此配置的示例位于 Maintaining Multiple Isolation Levels for a Single Engine。
另一个示例是使用一个自定义选项shard_id
,该选项由事件消耗以在数据库连接上更改当前模式:
from sqlalchemy import event from sqlalchemy.engine import Engine primary_engine = create_engine("mysql+mysqldb://") shard1 = primary_engine.execution_options(shard_id="shard1") shard2 = primary_engine.execution_options(shard_id="shard2") shards = {"default": "base", "shard_1": "db1", "shard_2": "db2"} @event.listens_for(Engine, "before_cursor_execute") def _switch_shard(conn, cursor, stmt, params, context, executemany): shard_id = conn.get_execution_options().get('shard_id', "default") current_shard = conn.info.get("current_shard", None) if current_shard != shard_id: cursor.execute("use %s" % shards[shard_id]) conn.info["current_shard"] = shard_id
上述示例展示了两个Engine
对象,它们分别用作工厂,用于创建具有预先建立的“shard_id”执行选项的Connection
对象。然后,ConnectionEvents.before_cursor_execute()
事件处理程序解释此执行选项,以在语句执行之前发出 MySQL use
语句以切换数据库,同时使用Connection.info
字典跟踪我们已经建立的数据库。
参见
Connection.execution_options()
- 更新Connection
对象上的执行选项。
Engine.update_execution_options()
- 更新给定Engine
的执行选项。
Engine.get_execution_options()
method get_execution_options() → _ExecuteOptions
获取执行期间将生效的非 SQL 选项。
参见
Engine.execution_options()
attribute name
正在使用的Engine
的Dialect
的字符串名称。
method raw_connection() → PoolProxiedConnection
从连接池返回“原始”DBAPI 连接。
返回的对象是底层驱动程序正在使用的 DBAPI 连接对象的代理版本。该对象将具有与真实的 DBAPI 连接相同的所有行为,只是它的close()
方法将导致连接返回到池中,而不是真正关闭。
当Connection
对象已经存在时,可以使用Connection.connection
访问器获取 DBAPI 连接。
另请参阅
使用驱动程序 SQL 和原始 DBAPI 连接
method update_execution_options(**opt: Any) → None
更新此Engine
的默认execution_options
字典。
在**opt 中给定的键/值将添加到将用于所有连接的默认执行选项中。此字典的初始内容可以通过execution_options
参数发送到create_engine()
。
另请参阅
Connection.execution_options()
Engine.execution_options()
class sqlalchemy.engine.ExceptionContext
封装正在进行中的错误条件的信息。
成员
chained_exception, connection, cursor, dialect, engine, execution_context, invalidate_pool_on_disconnect, is_disconnect, is_pre_ping, original_exception, parameters, sqlalchemy_exception, statement
此对象仅用于传递给DialectEvents.handle_error()
事件,支持可在不向后不兼容地扩展的接口。
attribute chained_exception: BaseException | None
如果有的话,前一个处理程序在异常链中返回的异常。
如果存在,则此异常将最终由 SQLAlchemy 引发,除非后续处理程序替换它。
可能为 None。
attribute connection: Connection | None
异常发生时使用的Connection
。
此成员存在,除非首次连接失败。
另请参阅
ExceptionContext.engine
attribute cursor: DBAPICursor | None
DBAPI 游标对象。
可能为 None。
attribute dialect: Dialect
正在使用的Dialect
。
此成员对所有事件钩子的调用都存在。
在 2.0 版中新增。
attribute engine: Engine | None
发生异常时正在使用的Engine
。
除了在连接池“预连接”过程中处理错误时,此成员在所有情况下都存在。
attribute execution_context: ExecutionContext | None
正在进行的执行操作对应的ExecutionContext
。
对于语句执行操作,此标志存在,但对于诸如事务开始/结束之类的操作则不存在。当在构造ExecutionContext
之前引发异常时,此标志也不存在。
请注意,ExceptionContext.statement
和ExceptionContext.parameters
成员可能表示与ExecutionContext
的不同值,可能是在ConnectionEvents.before_cursor_execute()
事件或类似事件修改了要发送的语句/参数的情况下。
可能为 None。
attribute invalidate_pool_on_disconnect: bool
表示在“断开连接”条件生效时是否应使池中的所有连接失效。
在DialectEvents.handle_error()
事件的范围内将此标志设置为 False 将导致在断开连接时不会使池中的所有连接失效;只有实际上受到错误影响的当前连接将被使失效。
此标志的目的是用于自定义断开连接处理方案,在此方案中,池中其他连接的失效是基于其他条件进行的,甚至是基于每个连接的条件进行的。
attribute is_disconnect: bool
表示发生的异常是否代表“断开连接”条件。
在DialectEvents.handle_error()
处理程序的范围内,此标志将始终为 True 或 False。
SQLAlchemy 将推迟到此标志以确定是否随后应使连接失效。也就是说,通过分配给此标志,可以通过更改此标志来调用或阻止连接和池失效的“断开”事件。
注意
使用create_engine.pool_pre_ping
参数启用的池“pre_ping”处理程序在决定“ping”返回 false 而不是接收到未处理错误之前不会查看此事件。对于这种用例,可以使用基于 engine_connect()的遗留配方。将来的 API 允许在所有功能中更全面地自定义“断开”检测机制。
attribute is_pre_ping: bool
指示此错误是否发生在设置create_engine.pool_pre_ping
为True
时执行的“pre-ping”步骤中。在此模式下,ExceptionContext.engine
属性将为None
。正在使用的方言可通过ExceptionContext.dialect
属性访问。
版本 2.0.5 中的新功能。
attribute original_exception: BaseException
被捕获的异常对象。
此成员始终存在。
attribute parameters: _DBAPIAnyExecuteParams | None
直接发送到 DBAPI 的参数集合。
可能是 None。
attribute sqlalchemy_exception: StatementError | None
包装原始异常的sqlalchemy.exc.StatementError
,如果未绕过事件处理,则将引发该异常。
可能为 None,因为不是所有的异常类型都被 SQLAlchemy 包装。对于子类化 dbapi 的 Error 类的 DBAPI 级别异常,此字段将始终存在。
attribute statement: str | None
直接发送到 DBAPI 的字符串 SQL 语句。
可能是 None。
class sqlalchemy.engine.NestedTransaction
表示“嵌套”或 SAVEPOINT 事务。
NestedTransaction
对象是通过调用Connection.begin_nested()
方法创建的Connection
。
使用NestedTransaction
时,“begin”/“commit”/“rollback”的语义如下:
- “begin”操作对应于“BEGIN SAVEPOINT”命令,其中保存点被赋予一个显式名称,该名称是此对象状态的一部分。
NestedTransaction.commit()
方法对应于“RELEASE SAVEPOINT”操作,使用与此NestedTransaction
关联的保存点标识符。NestedTransaction.rollback()
方法对应于“ROLLBACK TO SAVEPOINT”操作,使用与此NestedTransaction
关联的保存点标识符。
模仿外部事务的语义以便代码可以以一种不可知的方式处理“保存点”事务和“外部”事务。
另请参阅
使用 SAVEPOINT - SAVEPOINT API 的 ORM 版本。
成员
close(), commit(), rollback()
类签名
类sqlalchemy.engine.NestedTransaction
(sqlalchemy.engine.Transaction
)
method close() → None
继承自 Transaction.close()
方法的 Transaction
关闭此Transaction
。
如果此事务是嵌套的开始/提交中的基本事务,则事务将回滚。否则,该方法将返回。
这用于取消事务而不影响封闭事务的范围。
method commit() → None
继承自 Transaction.commit()
方法的 Transaction
提交此Transaction
。
这个实现可能会根据使用的事务类型而有所不同:
- 对于简单的数据库事务(例如
RootTransaction
),它对应于一个 COMMIT。 - 对于
NestedTransaction
,它对应于“RELEASE SAVEPOINT”操作。 - 对于
TwoPhaseTransaction
,可以使用特定于 DBAPI 的两阶段事务方法。
method rollback() → None
继承自 Transaction.rollback()
方法的 Transaction
回滚此Transaction
。
此实现可能根据使用的事务类型而有所不同:
- 对于简单的数据库事务(例如
RootTransaction
),它对应于一个 ROLLBACK。 - 对于
NestedTransaction
,它对应于“ROLLBACK TO SAVEPOINT”操作。 - 对于
TwoPhaseTransaction
,可以使用特定于 DBAPI 的两阶段事务方法。
class sqlalchemy.engine.RootTransaction
表示Connection
上的“根”事务。
这对应于当前正在为Connection
执行的“BEGIN/COMMIT/ROLLBACK”。通过调用Connection.begin()
方法创建RootTransaction
,并且在其活动范围内与Connection
关联。当前使用的RootTransaction
可通过Connection.get_transaction
方法访问Connection
。
在 2.0 style 中使用时,Connection
还采用“autobegin”行为,每当处于非事务状态的连接用于在 DBAPI 连接上发出命令时,就会创建一个新的RootTransaction
。在 2.0 style 使用中,RootTransaction
的范围可以使用Connection.commit()
和Connection.rollback()
方法进行控制。
成员
close(), commit(), rollback()
SqlAlchemy 2.0 中文文档(四十四)(5)https://developer.aliyun.com/article/1563072