SqlAlchemy 2.0 中文文档(五十八)(3)https://developer.aliyun.com/article/1563135
2.0.0b1
发布日期:2022 年 10 月 13 日
常规
- [常规] [更改]迁移代码库以删除所有之前标记为在 2.0 中移除的预先 2.0 版本行为和架构,包括但不限于:
- 删除所有 Python 2 代码,最低版本现在为 Python 3.7
Engine
和Connection
现在使用新的 2.0 工作风格,其中包括 “autobegin”,库级别的自动提交已删除,子事务和 “branched” 连接已删除。- 结果对象使用 2.0 风格的行为;
Row
完全是一个具有命名元组而没有 “映射” 行为,使用RowMapping
来进行 “映射” 行为 - 所有 Unicode 编码/解码架构已从 SQLAlchemy 中删除。所有现代的 DBAPI 实现都通过 Python 3 透明地支持 Unicode,因此已经删除了
convert_unicode
功能以及相关的在 DBAPIcursor.description
等中查找字节字符串的机制。 - 从
MetaData
,Table
和从以前可以引用 “绑定引擎”的所有 DDL/DML/DQL 元素中的.bind
属性和参数 - 独立的
sqlalchemy.orm.mapper()
函数已移除;所有经典映射应通过registry.map_imperatively()
方法的registry
进行。 Query.join()
方法不再接受字符串作为关系名称;使用Class.attrname
作为连接目标的长期记录方法现在是标准的。Query.join()
不再接受“aliased”和“from_joinpoint”参数。Query.join()
不再在一个方法调用中接受多个连接目标链。Query.from_self()
,Query.select_entity_from()
和Query.with_polymorphic()
已移除。relationship.cascade_backrefs
参数现在必须保持其新默认值False
;save-update
级联不再沿着反向引用级联。Session.future
参数必须始终设置为True
。Session
的 2.0 风格事务模式现在始终生效。- 加载器选项不再接受属性名称的字符串。使用
Class.attrname
作为加载器选项目标的长期记录方法现在是标准的。 - 遗留形式的
select()
已移除,包括select([cols])
,some_table.select()
的“whereclause”和关键参数。 Select
上的遗留“就地变异器”方法,如append_whereclause()
,append_order_by()
等已移除。- 移除了非常古老的“dbapi_proxy”模块,早期 SQLAlchemy 版本中用于在原始 DBAPI 连接上提供透明连接池。
- 参考:#7257
- [通用] [更改]
Query.instances()
方法已弃用。该方法的行为约定,即可以通过任意结果集迭代对象,早已过时且不再测试。可以使用类似:meth.Select.from_statement
或aliased()
的构造来返回对象。
平台
- [平台] [特性]
SQLAlchemy 的 C 扩展已被全部使用 Cython 编写的新实现所取代。与以前的 C 扩展一样,针对许多常见平台的预构建轮文件可在 pypi 上获得,因此构建不是问题。对于自定义构建,python setup.py build_ext
与以前一样工作,只需额外的 Cython 安装即可。pyproject.toml
现在也是源代码的一部分,当使用 pip 时将建立正确的构建依赖关系。
参见
C 扩展现已移植到 Cython
参考:#7256 - [platform] [change]
SQLAlchemy 的源代码构建和安装现在包括一个pyproject.toml
文件,以完全支持 PEP 517。
参见
安装现在完全支持 pep-517
参考:#7311
orm
- [orm] [feature] [sql]
添加了对所有支持 RETURNING 的包含方言的新功能,称为“insertmanyvalues”。这是“fast executemany”功能的一般化,该功能首先在 psycopg2 驱动程序中的 1.4 版本中引入,详情请参阅 ORM Batch inserts with psycopg2 now batch statements with RETURNING in most cases,它允许 ORM 将 INSERT 语句批处理到一个更高效的 SQL 结构中,同时仍能够使用 RETURNING 检索新生成的主键和 SQL 默认值。
此功能现在适用于支持 RETURNING 以及多个 VALUES 构造用于 INSERT 的许多方言,包括所有 PostgreSQL 驱动程序,SQLite,MariaDB,MS SQL Server。另外,Oracle 方言还使用本机 cx_Oracle 或 OracleDB 功能获得相同的能力。
参考:#6047 - [orm] [feature]
添加了新参数AttributeEvents.include_key
,它将包含诸如__setitem__()
(例如obj[key] = value
)和__delitem__()
(例如del obj[key]
)等操作的字典或列表键,使用一个新的关键字参数“key”或“keys”,取决于事件,例如AttributeEvents.append.key
,AttributeEvents.bulk_replace.keys
。这允许事件处理程序考虑传递给操作的键,对于与MappedCollection
一起工作的字典操作尤其重要。
参考:#8375 - [orm] [feature]
添加了新参数Operators.op.python_impl
,可从Operators.op()
以及直接使用custom_op
构造函数时使用,允许提供一个在 Python 中进行评估的函数,以及自定义 SQL 运算符。当操作符对象在两侧使用普通 Python 对象作为操作数时,此评估函数将成为使用的实现,并且特别兼容与 ORM 启用的 INSERT、UPDATE 和 DELETE 语句一起使用的synchronize_session='evaluate'
选项。
参考:#3162 - [orm] [feature]
Session
(以及间接AsyncSession
)现在具有新的状态跟踪功能,将主动捕获在特定事务方法进行时发生的任何意外状态更改。这是为了允许在线程不安全的方式中使用Session
的情况,其中事件钩子或类似的可能在操作中调用意外方法,以及在其他并发情况下(如 asyncio 或 gevent)在首次发生非法访问时引发信息性消息,而不是默默传递导致由于Session
处于无效状态而导致的次要故障。
另请参阅
当检测到非法并发或重入访问时,会主动引发会话
参考:#7433 - [orm] [feature]
当与 Pythondataclass
一起使用时,composite()
映射构造现在支持值的自动解析;不再需要实现__composite_values__()
方法,因为此方法是从数据类的检查中派生的。
此外,由composite
映射的类现在支持排序比较操作,例如<
、>=
等。
请参阅复合列类型中的新文档以获取示例。 - [orm] [feature]
添加了对selectinload()
和immediateload()
加载器选项的非常实验性功能,名为selectinload.recursion_depth
/immediateload.recursion_depth
,它允许单个加载器选项自动递归到自引用关系中。设置为指示深度的整数,并且也可以设置为-1,以指示继续加载直到找不到更多层级为止。对selectinload()
和immediateload()
进行了主要的内部更改,以便使此功能在继续正确使用编译缓存的同时工作,并且不使用任意递归,因此支持任何深度级别(尽管会发出相同数量的查询)。这对于必须完全急切加载的自引用结构可能会有用,例如在使用 asyncio 时。
当检测到相关对象加载中的过度递归深度时,还会发出警告,该警告也会在加载器选项以任意长度连接在一起时(即,不使用新的recursion_depth
选项)发出。此操作继续使用大量内存,并且性能极差;当检测到此条件时,缓存会被禁用,以防止缓存被任意语句淹没。
参考:#8126 - [orm] [feature]
添加了新参数Session.autobegin
,当设置为False
时,将阻止Session
隐式地开始事务。必须首先显式调用Session.begin()
方法,以便继续进行操作,否则在任何操作本应自动开始时都会引发错误。此选项可用于创建一个“安全”的Session
,该会话不会隐式启动新事务。
作为这一变化的一部分,还添加了一个新的状态变量origin
,可能对事件处理代码有用,以了解特定SessionTransaction
的来源。
参考:#6928 - [orm] [特性]
使用包含ForeignKey
引用的Column
对象的声明性混合物不再需要使用declared_attr()
来实现此映射;当列应用于声明的映射时,ForeignKey
对象与Column
本身一起复制。 - [orm] [用例]
在load_only()
加载器选项中添加了load_only.raiseload
参数,以便未加载的属性可能具有“raise”行为而不是延迟加载。以前没有真正直接使用load_only()
选项来实现这一点。 - [orm] [更改]为了更好地适应显式类型,一些通常在内部构造但有时也可见于消息传递和类型化的 ORM 构造的名称已更改为更简洁的名称,这些名称也与构造函数的名称(大小写不同)匹配,在所有情况下都保留了旧名称的别名以备将来使用:
RelationshipProperty
成为主要名称Relationship
的别名,始终由relationship()
函数构建SynonymProperty
成为主要名称Synonym
的别名,始终由synonym()
函数构建CompositeProperty
现在成为主要名称Composite
的别名,始终由composite()
函数构建。
- [orm] [change]
为了与突出的 ORM 概念Mapped
保持一致,基于字典的集合attribute_mapped_collection()
、column_mapped_collection()
和MappedCollection
的名称已更改为attribute_keyed_dict()
、column_keyed_dict()
和KeyFuncDict
,使用“dict”短语以减少与术语“mapped”的混淆。旧名称将无限期保留,没有删除计划。
参考:#8608 - [orm] [bug]
所有Result
对象现在在硬关闭后使用时都会一致地引发ResourceClosedError
,包括在调用类似Result.first()
和Result.scalar()
这样的“单行或值”方法后发生的“硬关闭”。这已经是基于CursorResult
的最常见的 Core 语句执行返回的结果对象的行为,因此这种行为并不新鲜。然而,这一变化已经扩展到正确地适应使用 2.0 风格 ORM 查询时返回的 ORM“过滤”结果对象,以前这些对象会以“软关闭”方式返回空结果,或者根本不会真正“软关闭”并会继续从底层游标中产生结果。
作为这一变更的一部分,还将Result.close()
添加到基础Result
类中,并为 ORM 使用的过滤结果实现了它,这样就可以在使用yield_per
执行选项时调用底层CursorResult
上的CursorResult.close()
方法,在获取剩余的 ORM 结果之前关闭服务器端游标。这对于核心结果集已经可用,但此变更也使其适用于 2.0 风格的 ORM 结果。
此更改也回溯到:1.4.27
参考:#7274 - [orm] [bug]
修复了registry.map_declaratively()
方法返回内部“映射器配置”对象而不是 API 文档中所述的Mapper
对象的问题。 - [orm] [bug]
修复了至少在 1.3 版本中出现的性能回归,如果不是更早(在 1.0 之后的某个时候),那么从连接的继承子类加载延迟列(那些明确映射为defer()
的列,而不是已过期的未延迟列),将不会使用“优化”查询,该查询仅查询包含未加载列的直接表,而是运行完整的 ORM 查询,该查询会为所有基本表发出 JOIN,当仅从子类加载列时,这是不必要的。
参考:#7463 - [orm] [bug]
Load
对象及相关加载策略模式的内部大部分已经重写,以利用现在仅支持属性绑定路径而不是字符串的事实。重写希望能更直接地解决加载策略系统中的新用例和微妙问题。
参考:#6986 - [orm] [bug]
对“延迟加载”/“仅加载”一组策略选项进行了改进,其中如果一个对象从一个查询中的两个不同逻辑路径加载,那么至少有一个选项配置为填充的属性将在所有情况下被填充,即使该对象的其他加载路径没有设置此选项。以前,基于随机性来确定哪个“路径”首先处理对象。
参考:#8166 - [orm] [bug]
修复了在针对联合继承子类创建语句时启用 ORM 的 UPDATE 时出现的问题,仅更新本地表列,其中“fetch”同步策略不会为使用 RETURNING 进行获取同步的数据库呈现正确的 RETURNING 子句。还调整了在 UPDATE FROM 和 DELETE FROM 语句中使用的 RETURNING 策略。
参考:#8344 - [orm] [bug] [asyncio]
从begin
和begin_nested
中删除了未使用的**kw
参数。这些 kw 没有被使用,似乎是错误地添加到 API 中的。
参考:#7703 - [orm] [bug]
更改了attribute_mapped_collection()
和column_mapped_collection()
(现在称为attribute_keyed_dict()
和column_keyed_dict()
)在填充字典时使用的属性访问方法,断言对象上用作字典键的数据值实际上存在,并且不是因为属性从未被分配而使用“None”。这用于防止在通过反向引用进行分配时错误地为键分配 None,其中对象上的“键”属性尚未被分配。
由于此处的失败模式是一种通常不会持续到数据库的瞬态条件,并且很容易通过类的构造函数根据分配参数的顺序产生,因此很有可能许多应用程序已经包含了这种行为,而这种行为被悄悄地忽略了。为了适应现在引发此错误的应用程序,还添加了一个新参数attribute_keyed_dict.ignore_unpopulated_attribute
到attribute_keyed_dict()
和column_keyed_dict()
,这个参数将导致错误的反向引用赋值被跳过。
参考:#8372 - [orm] [bug]
添加了新参数AbstractConcreteBase.strict_attrs
到AbstractConcreteBase
声明混合类。这个参数的效果是,子类上的属性范围正确地限制在声明每个属性的子类中,而不是之前的行为,其中整个层次结构的所有属性都应用到基本的“抽象”类上。这样会产生更清晰、更正确的映射,子类不再具有仅对同级类有用的属性。此参数的默认值为 False,这保留了先前的行为不变;这是为了支持在查询中明确使用这些属性的现有代码。要迁移到更新的方法,根据需要将显式属性应用到抽象基类中。
参考:#8403 - [orm] [bug]
defer()
在处理主键和“多态鉴别器”列时的行为已经修订,以使这些列不再是可延迟的,无论是明确指定还是使用诸如defer('*')
这样的通配符。先前,通配符延迟不会加载主键/多态列,这导致在所有情况下都出现错误,因为 ORM 依赖于这些列来生成对象标识。对主键列的显式延迟行为不变,因为这些延迟已经被隐式忽略。
参考:#7495 - [orm] [bug]
修复了Mapper.eager_defaults
参数行为中的错误,使得仅在表定义中存在客户端 SQL 默认值或 onupdate 表达式时,ORM 为行执行 INSERT 或 UPDATE 时触发 RETURNING 或 SELECT 的操作。之前,仅服务器端默认值作为表 DDL 的一部分或服务器端 onupdate 表达式会触发此次提取,尽管客户端 SQL 表达式在渲染提取时也会被包含在内。
参考:#7438
引擎
- [引擎] [特性]
DialectEvents.handle_error()
事件现已从EngineEvents
套件移至DialectEvents
套件,并且现在参与连接池的“预 ping”事件,对于那些使用断开代码来检测数据库是否存活的方言。这使得最终用户代码能够更改“预 ping”的状态。请注意,这不包括包含本地“ping”方法的方言,如 psycopg2 或大多数 MySQL 方言。
参考:#5648 - [引擎] [特性]
ConnectionEvents.set_connection_execution_options()
和ConnectionEvents.set_engine_execution_options()
事件钩子现在允许对给定的选项字典进行就地修改,新内容将作为最终执行选项接收。以前,不支持对字典进行就地修改。 - [引擎] [用例]
将create_engine.isolation_level
参数泛化到基本方言,因此不再依赖于单独的方言。该参数为所有新数据库连接的“隔离级别”设置提供了设置,一旦连接池创建它们,该值就会保持设置而不是在每次 checkin 时重置。create_engine.isolation_level
参数在功能上与通过Engine.execution_options.isolation_level
参数使用Engine.execution_options()
设置相当。区别在于前者设置隔离级别只会在创建连接时执行一次,后者在每次连接检出时设置和重置给定级别。
参考:#6342 - [engine] [change]关于引擎和方言的一些小的 API 更改:
Dialect.set_isolation_level()
、Dialect.get_isolation_level()
、:meth: 方言方法将始终传递原始的 DBAPI 连接Connection
和Engine
类不再共享基础的Connectable
超类,该超类已被移除。- 添加了一个新的接口类
PoolProxiedConnection
- 这是熟悉的_ConnectionFairy
类的公共接口,尽管它是一个私有类。
- 参考:#7122
- [engine] [bug] [regression]
修复了当结果完全耗尽时,CursorResult.fetchmany()
方法未能自动关闭服务器端游标(即在使用stream_results
或yield_per
时,无论是核心还是 ORM 导向的结果)的回归问题。
此更改也被回溯至:1.4.27
参考:#7274 - [engine] [bug]
修复了未来Engine
中的问题,当调用Engine.begin()
并进入上下文管理器时,如果实际的 BEGIN 操作由于某种原因失败,例如事件处理程序引发异常,则连接不会关闭;未来版本的引擎未测试此用例。请注意,“未来”上下文管理器在实际输入上下文管理器之前不会运行 “BEGIN” 操作。这与立即运行 “BEGIN” 操作的传统版本不同。
此更改也被回溯至:1.4.27
参考:#7272 - [engine] [bug]
当pool_size=0
时,QueuePool
现在会忽略max_overflow
,从而正确地使池在所有情况下都是无限的。
参考:#8523 - [engine] [bug]
为了提高安全性,当调用str(url)
时,URL
对象现在默认使用密码混淆。要将 URL 字符串化为明文密码,可以使用URL.render_as_string()
,将URL.render_as_string.hide_password
参数传递为False
。感谢我们的贡献者提供了此拉取请求。
另请参阅
str(engine.url) 现在默认混淆密码
参考:#8567 - [engine] [bug]
Inspector.has_table()
方法现在将一致地检查给定名称的视图和表格。先前,此行为取决于方言,其中 PostgreSQL、MySQL/MariaDB 和 SQLite 支持它,而 Oracle 和 SQL Server 不支持它。第三方方言也应确保它们的Inspector.has_table()
方法搜索给定名称的视图和表格。
参考:#7161 - [engine] [bug]
在Result.columns()
方法中修复了一个问题,在某些情况下,特别是 ORM 结果对象的情况下,调用带有单个索引的Result.columns()
可能导致Result
生成标量对象而不是Row
对象,就像调用了Result.scalars()
方法一样。在 SQLAlchemy 1.4 中,此场景会发出警告,指出行为将在 SQLAlchemy 2.0 中更改。
引用:#7953 - [engine] [错误]
将DefaultGenerator
对象(例如Sequence
)传递给Connection.execute()
方法已弃用,因为此方法被类型化为返回一个CursorResult
对象,而不是纯标量值。应改用Connection.scalar()
方法,该方法已经重写了新的内部代码路径以适用于调用 SELECT 以获取默认生成对象而不经过Connection.execute()
方法。 - [engine] [已移除]
从create_engine()
中移除了之前弃用的case_sensitive
参数,这只会影响 Core-only 结果集行中字符串列名称的查找;它不会影响 ORM 的行为。case_sensitive
指向的有效行为保持其默认值True
,意味着在row._mapping
中查找的字符串名称将与大小写敏感地匹配,就像任何其他 Python 映射一样。
请注意,case_sensitive
参数与控制大小写敏感性、引用和“名称规范化”(即转换为将所有大写字母视为大小写不敏感的数据库)DDL 标识符名称的一般主题没有任何关系,这仍然是 SQLAlchemy 的一个常规核心功能。 - [engine] [已移除]
移除了已弃用的旧版包sqlalchemy.databases
。请改用sqlalchemy.dialects
。
引用:#7258 - [engine] [已弃用]
create_engine.implicit_returning
参数已经在create_engine()
函数中弃用;该参数仅在Table
对象上保留。该参数最初旨在在 SQLAlchemy 首次开发时启用“implicit returning”功能,但默认情况下未启用。在现代用法下,没有理由禁用该参数,并且观察到它会引起混乱,因为它会降低性能,使 ORM 更难以检索最近插入的服务器默认值。该参数仅在Table
上保留,以特别适应使 RETURNING 不可行的数据库级边缘情况,目前唯一的示例是 SQL Server 的限制,即不得在具有 INSERT 触发器的表上使用 INSERT RETURNING。
参考:#6962
sql
- [sql] [feature]
添加了长期要求的不区分大小写的字符串操作符
ColumnOperators.icontains()
,ColumnOperators.istartswith()
,ColumnOperators.iendswith()
。这些操作符生成不区分大小写的 LIKE 组合(在 PostgreSQL 上使用 ILIKE,在所有其他后端上使用 LOWER()函数),以补充现有的 LIKE 组合操作符ColumnOperators.contains()
,ColumnOperators.startswith()
等。对于实现这些新方法的 Matias Martinez Rebori 的细致和完整的工作表示巨大的感谢。
- 参考:#3482
- [sql] [feature]
在所有FromClause
对象的FromClause.c
集合中添加了新的语法,允许传递键的元组给__getitem__()
,以及支持select()
构造处理直接处理结果类似元组的集合,允许select(table.c['a', 'b', 'c'])
语法成为可能。返回的子集合本身也是一个ColumnCollection
,现在也可以直接被select()
和类似方法消耗。
参见
设置 COLUMNS 和 FROM 子句
参考:#8285 - [sql] [功能]
添加了新的与后端无关的Uuid
数据类型,从 PostgreSQL 方言泛化到核心类型,以及将UUID
从 PostgreSQL 方言迁移到核心类型。SQL Server 的UNIQUEIDENTIFIER
数据类型也变成了一个 UUID 处理数据类型。感谢 Trevor Gross 的帮助。
参考:#7212 - [sql] [功能]
向sqlalchemy.
模块命名空间添加了Double
、DOUBLE
、DOUBLE_PRECISION
数据类型,用于显式使用 double/double precision 以及通用的“double”数据类型。使用Double
来提供通用支持,根据不同后端需要解析为 DOUBLE/DOUBLE PRECISION/FLOAT。
参考:#5465 - [sql] [用例]
更改了Insert
构造的编译机制,使得“自动递增主键”列值将通过cursor.lastrowid
或 RETURNING 获取,即使它存在于参数集中或在Insert.values()
方法中作为普通绑定值,用于特定后端上已知在明确传递 NULL 时仍生成自动递增值的单行 INSERT 语句。这恢复了 1.3 系列中的行为,用于分离的参数集以及Insert.values()
方法。在 1.4 中,参数集行为无意中更改为不再执行此操作,但Insert.values()
方法仍会获取自动递增值,直到 1.4.21,其中 #6770 再次无意中更改了行为,因为此用例从未得到覆盖。
现在已定义行为为“工作”,以适应数据库(如 SQLite、MySQL 和 MariaDB 等)忽略显式 NULL 主键值并仍调用自动递增生成器的情况。
引用: #7998 - [sql] [usecase]
当使用 PostgreSQL、MySQL、MariaDB、MSSQL、Oracle 方言提供的 SQL 编译器与literal_binds
一起使用时,添加了修改后的 ISO-8601 渲染(即将 T 转换为空格的 ISO-8601),对于 Oracle,ISO 格式被包装在适当的 TO_DATE() 函数调用内。先前,此渲染未针对方言特定编译实现。
另请参阅
DATE、TIME、DATETIME 数据类型现在在所有后端上支持文本渲染
引用: #5052 - [sql] [usecase]
添加了新的参数HasCTE.add_cte.nest_here
到HasCTE.add_cte()
,该参数将在父语句级别“嵌套”给定的CTE
。该参数等同于使用HasCTE.cte.nesting
参数,但在某些情况下可能更直观,因为它允许同时设置嵌套属性和 CTE 的显式级别。HasCTE.add_cte()
方法还接受多个 CTE 对象。
参考:#7759 - [sql] [bug]
当使用Select.select_from()
方法在select()
构造上建立 FROM 子句时,这些子句现在将首先在渲染的 SELECT 的 FROM 子句中呈现,这有助于保持子句的顺序,就像它们传递给Select.select_from()
方法本身时一样,而不受这些子句也在查询的其他部分提及的影响。如果Select
的其他元素也生成 FROM 子句,例如列子句或 WHERE 子句,这些将在由Select.select_from()
提供的子句之后呈现,假设它们未明确传递给Select.select_from()
。这一改进在某些情况下非常有用,其中特定数据库基于 FROM 子句的特定顺序生成理想的查询计划,并允许完全控制 FROM 子句的顺序。
参考:#7888 - [sql] [bug]
Enum.length
参数,用于为非本地枚举类型的VARCHAR
列设置长度,在为VARCHAR
数据类型发出 DDL 时现在无条件使用,包括当为目标后端设置了Enum.native_enum
参数为True
时继续使用VARCHAR
的情况。在这种情况下,先前该参数将被错误地忽略。先前为此情况发出的警告现已移除。
参考:#7791 - [sql] [bug]
Python 整数的原地类型检测,如表达式literal(25)
,现在也将应用基于值的适配,以适应 Python 大整数,其中确定的数据类型将是BigInteger
而不是Integer
。这适用于诸如 asyncpg 之类的方言,其既将隐式类型信息发送给驱动程序,又对数值刻度敏感。
参考:#7909 - [sql] [bug]
为所有“创建”/“删除”结构(包括CreateSequence
、DropSequence
、CreateIndex
、DropIndex
等)添加了if_exists
和if_not_exists
参数,允许在 DDL 中呈现通用的“IF EXISTS”/“IF NOT EXISTS”短语。感谢 Jesse Bakker 提供的拉取请求。
参考:#7354 - [sql] [bug]
改进了 SQL 二进制表达式的构造,以允许针对相同的关联操作符进行非常长的表达式,而无需特殊步骤以避免高内存使用和过度递归深度。现在,一个特定的二元操作A op B
可以与另一个元素op C
连接,结果结构将被“平铺”,以使表示以及 SQL 编译不需要递归。
此更改的一个影响是使用 SQL 函数的字符串连接表达式现在变得“平坦”,例如,MySQL 现在将呈现concat('x', 'y', 'z', ...)
而不是将两个元素函数嵌套在一起的concat(concat('x', 'y'), 'z')
。重写字符串连接运算符的第三方方言将需要实现一个新方法def visit_concat_op_expression_clauselist()
,以配合现有的def visit_concat_op_binary()
方法。
参考:#7744 - [sql] [bug]
使用“/”和“//”运算符实现了对“truediv”和“floordiv”的完全支持。Integer
类型的两个表达式之间的“truediv”操作现在被视为Numeric
类型,并且方言级别的编译将根据方言特定的基础将右操作数转换为数字类型,以确保实现 truediv。对于 floordiv,还添加了转换,对于那些默认情况下不执行 floordiv 的数据库(如 MySQL、Oracle),在这种情况下还会渲染FLOOR()
函数,以及右操作数不是整数的情况(对于 PostgreSQL 等其他数据库也是需要的)。
此更改解决了不同后端上除法运算符行为不一致的问题,并修复了 Oracle 上整数除法无法获取结果的问题,因为输出类型处理程序不合适的问题。
另见
Python 除法运算符对所有后端执行真除法;添加了地板除法
参考:#4926 - [sql] [bug]
在编译器中增加了额外的查找步骤,用于跟踪所有的 FROM 子句,这些子句是表,可能在多个模式中共享具有相同名称的情况,其中一个模式是隐式的“默认”模式;在这种情况下,当在没有模式限定符的情况下引用该名称时,编译器级别将为表名称生成一个匿名别名,以消除两个(或更多)名称的歧义。还考虑了使用服务器检测到的“默认模式名称”值对通常未限定名称进行模式限定的方法,但是这种方法不适用于 Oracle,SQL Server 也不接受,而且不适用于 PostgreSQL 搜索路径中的多个条目。在此解决的名称冲突问题已被确认至少影响到 Oracle、PostgreSQL、SQL Server、MySQL 和 MariaDB。
参考:#7471 - [sql] [bug]
从值的类型确定 SQL 类型的 Python 字符串值,主要是当使用literal()
时,现在将应用String
类型,而不是Unicode
数据类型,对于使用 Pythonstr.isascii()
测试为“ascii only”的 Python 字符串值。如果字符串不是isascii()
,则将绑定Unicode
数据类型,这在以前所有字符串检测中都使用了。这种行为仅适用于使用literal()
或其他没有现有数据类型的上下文的数据类型的就地检测,通常不适用于正常的Column
比较操作,其中正在比较的Column
的类型始终优先。
在诸如 SQL Server 等后端中,使用Unicode
数据类型可以确定文字字符串的格式化方式,其中文字值(即使用literal_binds
)将呈现为N''
而不是'value'
。对于常规绑定值处理,Unicode
数据类型还可能对传递值到 DBAPI 产生影响,再次以 SQL Server 为例,pyodbc 驱动程序支持使用 setinputsizes 模式,它将以不同方式处理String
与Unicode
。
参考:#7551 - [sql] [bug]
array_agg
现在将数组维度设置为 1。改进了对ARRAY
的处理,以接受None
值作为多维数组的值。
参考:#7083
架构
- [schema] [feature]
在ExecutableDDLElement
类(从DDLElement
重命名)实现的“条件 DDL”系统上进行了扩展,直接可用于SchemaItem
构造,如Index
、ForeignKeyConstraint
等,使得用于生成这些元素的条件逻辑包含在默认的 DDL 发射过程中。这个系统也可以被 Alembic 的未来版本支持,以支持所有模式管理系统中的条件 DDL 元素。
另请参阅
新的条件 DDL 用于约束和索引
参考:#7631 - [模式] [用例]
在DropConstraint
构造中添加了参数DropConstraint.if_exists
,这将导致“IF EXISTS” DDL 被添加到 DROP 语句中。这个短语不被所有数据库接受,如果数据库不支持它,该操作将在一个单独的 DDL 语句的范围内失败,因为在这个范围内没有类似的兼容回退。感谢 Mike Fiedler 的拉取请求。
参考:#8141 - [模式] [用例]
为所有包含不同的 CREATE 或 DROP 步骤的SchemaItem
对象实现了 DDL 事件钩子DDLEvents.before_create()
、DDLEvents.after_create()
、DDLEvents.before_drop()
、DDLEvents.after_drop()
,当该步骤被调用为一个独立的 SQL 语句时,包括ForeignKeyConstraint
、Sequence
、Index
和 PostgreSQL 的ENUM
。
参考:#8394 - [schema] [performance]
重构了模式反射 API,以允许参与的方言利用高性能的批量查询来一次反射多个表的模式,使用数量级较少的查询。新的性能特性首先针对 PostgreSQL 和 Oracle 后端,可以应用于使用 SELECT 查询反映表的系统目录表的任何方言。该变化还包括对Inspector
对象的新 API 特性和行为改进,包括像Inspector.has_table()
、Inspector.get_table_names()
等方法的一致、缓存行为,以及新方法Inspector.has_schema()
和Inspector.has_index()
。
另见
数据库反射的主要架构、性能和 API 增强 - 完整背景
参考:#4379 - [schema] [bug]
当使用Table.include_columns
参数排除后发现仍然是这些约束的一部分的列时,关于索引或唯一约束的反射发出的警告已被移除。当使用Table.include_columns
参数时,应该预期生成的Table
构造将不包括依赖于被省略列的约束。这个变化是对#8100作出的回应,该问题修复了Table.include_columns
与依赖于被省略列的外键约束的一起使用的情况,其中使用案例表明省略此类约束是可以预期的。
参考:#8102 - [schema] [postgresql]
对Constraint
对象添加了对评论的支持,包括 DDL 和反射;该字段已添加到基本的Constraint
类和相应的构造函数中,但目前只有 PostgreSQL 是支持该功能的后端。请参阅参数,如ForeignKeyConstraint.comment
,UniqueConstraint.comment
或CheckConstraint.comment
。
参考:#5677 - [schema] [mariadb] [mysql]添加对 MySQL 和 MariaDB 分区和示例页面的支持反映选项。这些选项存储在表方言选项字典中,因此以下关键字需要根据后端添加
mysql_
或mariadb_
前缀。支持的选项包括:
stats_sample_pages
partition_by
partitions
subpartition_by
- 当从数据库加载表时,这些选项也会反映出来,并将填充表
Table.dialect_options
。感谢 Ramon Will 的拉取请求。
参考:#4038
typing
- [typing] [improvement]
TypeEngine.with_variant()
方法现在返回原始TypeEngine
对象的副本,而不是将其包装在Variant
类中,该类实际上已被移除(导入符号仍保留以向后兼容可能测试此符号的代码)。虽然以前的方法保持了 Python 中的行为,但保持原始类型允许更清晰的类型检查和调试。TypeEngine.with_variant()
还可以在每次调用时接受多个方言名称,特别是对于相关的后端名称,如"mysql", "mariadb"
。
另请参阅
“with_variant()”克隆原始 TypeEngine 而不是更改类型
参考:#6980
postgresql
- [postgresql] [feature]
添加了新的 PostgreSQLDOMAIN
数据类型,其遵循与 PostgreSQLENUM
相同的 CREATE TYPE / DROP TYPE 行为。非常感谢 David Baumgold 的努力。
另见DOMAIN
参考:#7316 - [postgresql] [usecase] [asyncpg]
添加了可重写方法PGDialect_asyncpg.setup_asyncpg_json_codec
和PGDialect_asyncpg.setup_asyncpg_jsonb_codec
,用于在使用 asyncpg 时注册这些数据类型所需的 JSON/JSONB 编解码器。变更之处在于将方法拆分为单独的可重写方法,以支持需要修改或禁用这些特定编解码器设置的第三方方言。
此变更还被 回溯 到:1.4.27
参考:#7284 - [postgresql] [usecase]
为ARRAY
和ARRAY
数据类型添加了文字类型渲染。通用的字符串化将使用方括号进行渲染,例如[1, 2, 3]
,而 PostgreSQL 特定的将使用 ARRAY 文字,例如ARRAY[1, 2, 3]
。还考虑了多维和引号。
参考:#8138 - [postgresql] [usecase]
添加了对 PostgreSQL 多范围类型的支持,该类型引入于 PostgreSQL 14 中。现在已将对 PostgreSQL 范围和多范围的支持概括为 psycopg3、psycopg2 和 asyncpg 后端,并提供了进一步方言支持的空间,使用与以前使用的 psycopg2 对象兼容的后端无关Range
数据对象。请参阅新文档以了解使用模式。
此外,增强了范围类型处理,以便自动渲染类型转换,因此对于不提供任何上下文的语句的就地往返,不需要为数据库明确指定所需的类型(在 #8540 中讨论)。
非常感谢 @zeeeeeb 提交并测试新数据类型和 psycopg 支持的拉取请求。
另见
PostgreSQL 后端的新 RANGE / MULTIRANGE 支持和变更
范围和多范围类型
参考:#7156, #8540 - [postgresql] [usecase]
配置create_engine.pool_pre_ping
时发出的“ping”查询,对于 psycopg、asyncpg 和 pg8000,但不适用于 psycopg2,已更改为一个空查询(;
),而不是SELECT 1
;此外,对于 asyncpg 驱动程序,已修复了此查询不必要使用准备语句的问题。其理由是消除 PostgreSQL 在发出 ping 时产生查询计划的需要。当前不支持由psycopg2
驱动程序执行此操作,它继续使用SELECT 1
。
参考:#8491 - [postgresql] [change]
SQLAlchemy 现在要求 PostgreSQL 版本为 9 或更高。在某些有限的用例中,旧版本可能仍然可以工作。 - [postgresql] [change] [mssql]
UUID
的参数UUID.as_uuid
,以前专门针对 PostgreSQL 方言,现在已经泛化为 Core(连同一个新的与后端无关的Uuid
数据类型),现在默认为True
,表示此数据类型默认接受 PythonUUID
对象。此外,SQL Server 的UNIQUEIDENTIFIER
数据类型已转换为接收 UUID 的类型;对于使用字符串值的遗留代码,设置UNIQUEIDENTIFIER.as_uuid
参数为False
。
参考:#7225 - [postgresql] [change]
PostgreSQL 特定的ENUM
数据类型的ENUM.name
参数现在是一个必需的关键字参数。在任何情况下,“name”都是必要的,否则在 SQL/DDL 渲染时会引发错误。 - [postgresql] [change]
支持新的 PostgreSQL 功能,包括 psycopg3 方言以及扩展的“快速插入多个”支持,用于将绑定参数的类型信息传递给 PostgreSQL 数据库的系统已经重新设计,现在使用 SQL 编译器发出的内联转换,并且现在适用于所有 PostgreSQL 方言。这与以前的方法相反,以前的方法依赖于正在使用的 DBAPI 来自行呈现这些转换,例如 pg8000 和适应的 asyncpg 驱动程序的情况下,将使用 pep-249setinputsizes()
方法,或者对于 psycopg2 驱动程序,在大多数情况下将依赖于驱动程序本身,对于 ARRAY 则会做一些特殊的例外。
现在,所有 PostgreSQL 方言都使用 PostgreSQL 双冒号样式在编译器内呈现这些转换所需的转换,并且对于 PostgreSQL 方言,已删除了使用setinputsizes()
,因为这在任何情况���通常不是这些 DBAPI 的一部分(pg8000 是唯一的例外,它在 SQLAlchemy 开发人员的请求下添加了该方法)。
这种方法的优势包括每个语句的性能,因为在执行时不需要对编译后的语句进行第二次遍历,对所有 DBAPI 的更好支持,因为现在有一个一致的应用类型信息系统,以及改进的透明度,因为 SQL 日志输出以及编译语句的字符串输出将直接显示这些转换存在于语句中,而以前这些转换在日志输出中是不可见的,因为它们会在语句记录后发生。 - [postgresql] [错误]
Operators.match()
运算符现在在 PostgreSQL 全文搜索中使用plainto_tsquery()
,而不是to_tsquery()
。这种更改的理由是为了提供更好的与其他数据库后端上的 match 的跨兼容性。通过与Operators.bool_op()
(布尔运算符的改进版本Operators.op()
)结合使用func
,仍然可以通过使用所有 PostgreSQL 全文函数来获得完全支持。
另请参阅
PostgreSQL 上的 match()运算符使用 plainto_tsquery()而不是 to_tsquery()
参考:#7086 - [postgresql] [已移除]
移除对多个已弃用驱动程序的支持:
- 用于 PostgreSQL 的 pypostgresql。这作为外部驱动程序可在
github.com/PyGreSQL
获得。- 用于 PostgreSQL 的 pygresql。
- 请切换到受支持的驱动程序之一或同一驱动程序的外部版本。
参考:#7258 - [postgresql] [方言]
添加了对psycopg
方言的支持,支持同步和异步执行。此方言在create_engine()
和create_async_engine()
引擎创建函数下可用。
另请参阅
对 psycopg 3(又名“psycopg”)的方言支持
psycopg
参考:#6842 - [postgresql] [psycopg2]
更新了 psycopg2 方言,使用 DBAPI 接口执行两阶段事务。以前使用 SQL 命令处理这种类型的事务。
参考:#7238 - [postgresql] [schema]
引入了类型JSONPATH
,可在转换表达式中使用。在使用诸如jsonb_path_exists
或jsonb_path_match
这样接受jsonpath
作为输入的函数时,某些 PostgreSQL 方言需要这个类型。
另请参阅
JSON 类型 - PostgreSQL JSON 类型。
参考:#8216 - [postgresql] [reflection]
PostgreSQL 方言现在支持基于表达式的索引的反射。在使用Inspector.get_indexes()
时以及使用Table.autoload_with
反射Table
时都支持反射。感谢 immerrr 和 Aidan Kane 在这个问题上的帮助。
参考:#7442
mysql
- [mysql] [usecase] [mariadb]
ROLLUP
函数现在会在 MySql 和 MariaDB 上正确呈现WITH ROLLUP
,允许在这些后端使用 group by rollup。
参考:#8503 - [mysql] [bug]
修复了 MySQLInsert.on_duplicate_key_update()
中的问题,当在 VALUES 表达式中使用表达式时,会呈现错误的列名。感谢 Cristian Sabaila 提供的拉取请求。
此更改也 被后移 到:1.4.27
参考:#7281 - [mysql] [removed]
移除了对 OurSQL 驱动程序的支持,该驱动程序不再维护。
参考:#7258
mariadb
- [mariadb] [usecase]
添加了一个新的执行选项is_delete_using=True
,当使用 ORM 启用的 DELETE 语句与“fetch”同步策略一起使用时,该选项将被消耗;此选项表示预计 DELETE 语句将使用多个表,在 MariaDB 上是 DELETE…USING 语法。然后,该选项指示对于已知不支持“DELETE…USING…RETURNING”语法的数据库,不应使用在 MariaDB 中新实现的 SQLAlchemy 2.0 的 RETURNING(对于#7011)。尽管它们支持“DELETE…USING”,但它们不支持“DELETE…USING…RETURNING”语法,这是 MariaDB 的当前能力。
这个选项的原因是,ORM 启用的 DELETE 当前不知道 DELETE 语句是否针对多个表,直到编译发生,无论如何,编译都会被缓存,但需要知道这一点,以便事先发出用于待删除行的 SELECT。与为了预先检查所有 DELETE 语句以获取这种相对不寻常的 SQL 模式而对所有 DELETE 语句应用全面性能惩罚相比,通过在编译步骤中引发一个新的异常消息来请求is_delete_using=True
执行选项。此异常消息仅在以下情况下特定(且仅)引发:语句是启用了 ORM 的 DELETE,已请求“fetch”同步策略;后端是 MariaDB 或具有此特定限制的其他后端;已检测到初始编译中的语句,否则会发出“DELETE…USING…RETURNING”。通过应用执行选项,ORM 知道要首先运行一个 SELECT。ORM 启用的 UPDATE 也实现了类似的选项,但目前还没有需要它的后端。
参考:#8344 - [mariadb] [用例]
为 MariaDB 方言添加了 INSERT…RETURNING 和 DELETE…RETURNING 支持。UPDATE…RETURNING 尚未得到 MariaDB 的支持。从 10.5.0 开始,MariaDB 支持 INSERT…RETURNING,从 10.0.5 开始,支持 DELETE…RETURNING。
参考:#7011
sqlite
- [sqlite] [用例]
为 SQLite 的反射方法添加了一个名为sqlite_include_internal=True
的新参数;当省略时,以sqlite_
为前缀的本地表(根据 SQLite 文档,这些表被称为“内部模式”表,例如生成以支持“AUTOINCREMENT”列的sqlite_sequence
表),不会包含在返回本地对象列表的反射方法中。这样可以避免在使用 Alembic 自动生成时出现问题,以前会将这些由 SQLite 生成的表视为从模型中移除。
另请参阅
反射内部模式表
参考:#8234 - [sqlite] [用例]
为 SQLite 方言添加了 RETURNING 支持。自 SQLite 版本 3.35 起,SQLite 支持 RETURNING。
参考:#6195 - [sqlite] [用例]
SQLite 方言现在支持 UPDATE…FROM 语法,用于 UPDATE 语句可能在语句的 WHERE 条件中引用其他表而无需使用子查询。当使用Update
构造时,当使用多个表或其他实体或可选择时,此语法会自动调用。
参考:#7185 - [sqlite] [性能] [bug]
当使用基于文件的数据库时,SQLite 方言现在默认使用QueuePool
。这是与将check_same_thread
参数设置为False
一起设置的。已经观察到,默认使用NullPool
的先前方法,在释放数据库连接后不会保留连接,实际上会对性能产生可衡量的负面影响。如常,通过create_engine.poolclass
参数可以自定义池类。
参见
SQLite 方言为基于文件的数据库使用 QueuePool
参考:#7490 - [sqlite] [性能] [用例]
SQLite 的 datetime、date 和 time 数据类型现在使用 Python 标准库的fromisoformat()
方法来解析传入的 datetime、date 和 time 字符串值。这比以前基于正则表达式的方法提高了性能,还自动适应包含六位“微秒”格式或三位“毫秒”格式的 datetime 和 time 格式。
参考:#7029 - [sqlite] [bug]
移除了关于Numeric
类型发出的关于 DBAPI 不原生支持 Decimal 值的警告。这个警告是针对 SQLite 的,因为 SQLite 没有任何真正的方法(除非使用额外的扩展或解决方法)来处理超过 15 个有效数字的精度数值,因为它只使用浮点数来表示数字。由于这是 SQLite 本身已知且有文档记录的限制,而不是 pysqlite 驱动程序的怪癖,因此 SQLAlchemy 不需要为此发出警告。这个更改不会修改精度数值的处理方式。值可以继续按照Numeric
、Float
和相关数据类型配置为Decimal()
或float()
,只是在使用 SQLite 时无法保持超过 15 个有效数字的精度,除非使用字符串等替代表示方法。
参考:#7299
mssql
- [mssql] [用例]
实现了 SQL Server 方言的“clustered index” 标志mssql_clustered
的反射。感谢 John Lennox 提供的拉取请求。
参考:#8288 - [mssql] [用例]
在创建表时,为 MSSQL 添加了对表和列注释的支持。添加了反射表注释的支持。感谢 Daniel Hall 在此拉取请求中的帮助。
参考:#7844 - [mssql] [错误]
mssql+pyodbc
方言的use_setinputsizes
参数现在默认为True
;这样非 Unicode 字符串比较将由 pyodbc 绑定到 pyodbc.SQL_VARCHAR 而不是 pyodbc.SQL_WVARCHAR,从而使得对 VARCHAR 列的索引生效。为了让fast_executemany=True
参数继续正常工作,use_setinputsizes
模式现在在fast_executemany
为 True 且使用的具体方法是cursor.executemany()
时会跳过cursor.setinputsizes()
调用,因为该方法不支持 setinputsizes。此更改还为被标记为Unicode
或UnicodeText
的值添加了适当的 pyodbc DBAPI 类型,并将基础的JSON
数据类型修改为将 JSON 字符串值视为Unicode
而不是String
。
参考:#8177 - [mssql] [已移除]
由于缺乏测试支持,已移除对 mxodbc 驱动程序的支持。ODBC 用户可以使用完全受支持的 pyodbc 方言。
参考:#7258
oracle
- [oracle] [feature]
添加对新的 Oracle 驱动程序oracledb
的支持。
另请参阅
对 oracledb 的方言支持
python-oracledb
参考:#8054 - [oracle] [feature]
实现了FLOAT
数据类型的 DDL 和反射支持,其中包括显式的“binary_precision”值。使用特定于 Oracle 的FLOAT
数据类型,可以指定新参数FLOAT.binary_precision
,这将直接呈现 Oracle 的浮点类型精度。此值在反射期间解释。在反射回FLOAT
数据类型时,返回的数据类型是DOUBLE_PRECISION
(对于精度为 126 的FLOAT
,这也是 Oracle 的默认精度)、REAL
(对于精度为 63)、以及FLOAT
(对于自定义精度,按照 Oracle 文档)。
作为这一变更的一部分,当为 Oracle 生成 DDL 时,明确拒绝了通用的Float.precision
值,因为此精度无法准确转换为“二进制精度”;相反,错误消息鼓励使用TypeEngine.with_variant()
,以便精确选择 Oracle 的特定精度形式。这是一种与以往行为不兼容的更改,因为以前的“精度”值对于 Oracle 被静默地忽略。
另请参阅
新的 Oracle FLOAT 类型,具有二进制精度;不直接接受十进制精度
参考:#5465 - [oracle] [feature]对于 cx_Oracle 方言,完全实现了“RETURNING”支持,涵盖了两种个别功能:
- 实现了多行 RETURNING,意味着对于产生多于一个 RETURNING 行的 DML 语句,现在将收到多个 RETURNING 行。
- “executemany RETURNING” 也已实现 - 这允许当使用
cursor.executemany()
时,RETURNING 每个语句产生一行。这一特性的实现为 ORM 插入提供了显著的性能改进,就像 SQLAlchemy 1.4 变更 ORM Batch inserts with psycopg2 now batch statements with RETURNING in most cases 中为 psycopg2 添加的一样。
- 参考:#6245
- [oracle] [用例]
Oracle 现在将在 Oracle 12c 及以上版本中默认使用 FETCH FIRST N ROWS / OFFSET 语法来支持 limit/offset。当直接使用Select.fetch()
时,该语法已经可用,现在对Select.limit()
和Select.offset()
也适用。
参考:#8221 - [oracle] [更改]
在 Oracle 上,物化视图现在被反映为视图。在之前的 SQLAlchemy 版本中,视图会在表名中返回,而不在视图名中返回。由于此更改的副作用,默认情况下它们不会被MetaData.reflect()
反映,除非设置了views=True
。要获取物化视图列表,请使用新的检查方法Inspector.get_materialized_view_names()
。 - [oracle] [错误]
对 cx_Oracle 和 oracledb 方言中的 BLOB / CLOB / NCLOB 数据类型进行了调整,以根据 Oracle 开发人员的建议改善性能。
参考:#7494 - [oracle] [错误]
关于create_engine.implicit_returning
弃用的相关内容,现在 “implicit_returning” 特性在所有情况下都为 Oracle 方言启用;以前,当检测到 Oracle 8/8i 版本时,该特性会被关闭,然而在线文档显示这两个版本都支持与现代版本相同的 RETURNING 语法。
参考:#6962 - [oracle]
cx_Oracle 7 现在是 cx_Oracle 的最低版本。
杂项
- [已移除] [sybase]
删除了在之前的 SQLAlchemy 版本中已弃用的 “sybase” 内部方言。第三方方言支持可用。
另请参阅
外部方言
参考:#7258 - [已移除] [firebird]
移除了在以前的 SQLAlchemy 版本中已弃用的“firebird”内部方言。第三方方言支持可用。
另请参阅
外部方言
参考:#7258
2.0.30
无发布日期
orm
- [orm] [bug]
添加了新属性ORMExecuteState.is_from_statement
,用于检测形式为select().from_statement()
的语句,并增强了FromStatement
以根据发送到Select.from_statement()
方法本身的元素设置ORMExecuteState.is_select
、ORMExecuteState.is_insert
、ORMExecuteState.is_update
和ORMExecuteState.is_delete
。
参考:#11220
引擎
- [engine] [bug]
修复了Connection.execution_options.logging_token
选项中的问题,其中更改已经记录了消息的连接的logging_token
值不会更新以反映新的记录令牌。特别是这阻止了使用Session.connection()
在连接上更改选项,因为 BEGIN 记录消息已经被发出。
参考:#11210
typing
- [typing] [bug] [regression]
修复了在版本 2.0.29 中由 PR #11055引起的输入退化,该版本尝试将ParamSpec
添加到 asynciorun_sync()
方法中,其中使用AsyncConnection.run_sync()
与MetaData.reflect()
将由于 bug 在 mypy 上失败。有关详细信息,请参见github.com/python/mypy/issues/17093
。Pull request 由 Francisco R. Del Roio 提供。
参考:#11200
杂项
- [bug] [test]
在测试中使用subprocess.run
时,请确保PYTHONPATH
变量正确初始化。
参考:#11268
orm
- [orm] [bug]
添加了新属性ORMExecuteState.is_from_statement
,用于检测形式为select().from_statement()
的语句,并增强了FromStatement
以根据发送到Select.from_statement()
方法本身的元素设置ORMExecuteState.is_select
、ORMExecuteState.is_insert
、ORMExecuteState.is_update
和ORMExecuteState.is_delete
。
参考:#11220
engine
- [engine] [bug]
修复了Connection.execution_options.logging_token
选项中的问题,其中在已经记录了消息的连接上更改logging_token
的值不会更新以反映新的日志令牌。特别是这阻止了使用Session.connection()
在连接上更改选项,因为 BEGIN 日志消息已经被发出。
参考:#11210
typing
- [typing] [bug] [regression]
修复了由版本 2.0.29 中 PR #11055引起的类型回归,该 PR 试图将ParamSpec
添加到 asynciorun_sync()
方法中,其中在 mypy 上使用AsyncConnection.run_sync()
与MetaData.reflect()
会由于错误而在 mypy 上失败。有关详细信息,请参见github.com/python/mypy/issues/17093
。感谢 Francisco R. Del Roio 提供的拉取请求。
参考:#11200
misc
- [bug] [test]
在测试中使用subprocess.run
时,请确保PYTHONPATH
变量正确初始化。
参考:#11268
SqlAlchemy 2.0 中文文档(五十八)(5)https://developer.aliyun.com/article/1563137