2.0 更新日志

2.0.40

无发布日期

2.0.39

已发布: 2025 年 3 月 11 日

orm

  • [orm] [bug]

    修复了当使用 DML 返回(例如 Insert.returning())和一个 ORM 模型(该模型具有包含子查询的 column_property() 构造)时,会因内部错误而失败的错误。

    参考: #12326

  • [orm] [bug]

    修复了 ORM 启用的 UPDATE(理论上也包括 DELETE)中的错误,其中使用多表 DML 语句将不允许来自主 UPDATE 映射器以外的映射器的 ORM 映射列在 RETURNING 子句中命名;它们将被省略,并导致找不到列的异常。

    参考: #12328

  • [orm] [bug]

    修复了 select() 或其他 ORM 语句的 “is ORM” 标志不会基于多部分运算符表达式(例如 Cls.attr + Cls.attr + Cls.attr 或类似)传播到 ORM Session 的问题,从而导致此类语句未发生 ORM 行为。

    参考: #12357

  • [orm] [bug]

    修复了在 CTE 构造周围使用 aliased() 可能导致在单个语句中多次出现该别名构造时出现不适当的 “重复 CTE” 错误的问题。

    参考: #12364

sql

typing

asyncio

postgresql

  • [postgresql] [bug]

    为用于检索 IDENTITY 列结构的反射查询添加 SQL 类型,为查询添加显式 JSON 类型,以适应不支持原生 JSON 的异常 PostgreSQL 驱动程序配置。

    参考: #11751

  • [postgresql] [bug]

    修复了影响 PostgreSQL 17.3 及更高版本的问题,其中将 “NOT NULL” 作为其定义一部分的域的反射将在 PGInspector.get_domains() 返回的数据中包含一个无效的约束条目,该条目对应于不是 CHECK 约束的附加 “NOT NULL” 约束;字典中现有的 "nullable" 条目已指示域是否包含 “not null” 约束。请注意,由于 PostgreSQL 端的一个错误,PostgreSQL 17.0 至 17.2 也无法反映此类域;如果在反射包含 NOT NULL 的域时遇到错误,请升级到 PostgreSQL 服务器 17.3 或更高版本。

  • [postgresql] [bug]

    修复了 PostgreSQL 网络类型 INET, CIDR, MACADDR, MACADDR8 中的问题,其中将字符串值发送到与这些类型进行比较将呈现显式 CAST 到 VARCHAR,从而导致某些 SQL / 驱动程序组合失败。感谢 Denis Laxalde 的 pull request。

    参考: #12060

  • [postgresql] [bug]

    修复了 PostgreSQL 方言中的编译器问题,其中在使用子查询内部的 “FOR UPDATE OF” 时会传递不正确的关键字。

    参考: #12417

sqlite

  • [sqlite] [bug]

    修复了在同时配置 Table.sqlite_with_rowidTable.sqlite_strict 选项为非默认设置时,省略多个 SQLite 表扩展子句(当前为 WITH ROWIDSTRICT)之间逗号的问题。感谢 david-fed 的 pull request。

    参考: #12368

2.0.38

已发布: 2025 年 2 月 6 日

engine

  • [engine] [bug]

    修复了事件相关问题,其中多次在 Engine.execution_options() 上调用 Engine,同时使用事件注册参数(例如 isolation_level)会导致涉及事件注册的内部错误。

    参考: #12289

sql

  • [sql] [bug]

    重新组织了 FromClause 上的 .c 集合的生成方式的内部结构,使其能够抵抗并发访问集合。一个例子是创建 AliasSubquery 并将其作为模块级变量访问。这会影响使用此类模块级全局别名对象的 Oracle 方言,但也具有一般用途。

    参考: #12302

  • [sql] [bug]

    修复了影响缓存的 SQL 组合错误,其中在 in_() 表达式内部使用 None 值将绕过 IN 构造使用的常用 “扩展绑定参数” 逻辑,从而允许进行适当的缓存。

    参考: #12314

postgresql

  • [postgresql] [usecase] [asyncio]

    在 asyncpg 驱动程序的连接终止过程中添加了一个额外的 asyncio.shield() 调用,以缓解在 anyio 并发库下阻止终止完成的问题。

    参考: #12077

  • [postgresql] [bug]

    调整了 asyncpg 连接包装器,以便发送到 asyncpg 的 connection.transaction() 调用为 isolation_level 发送 None(如果未在 SQLAlchemy 方言/包装器中另行设置),从而允许 asyncpg 在缺少客户端级别设置的情况下使用服务器级别设置 isolation_level。以前,asyncpg 的此行为被硬编码的 read_committed 阻止。

    参考: #12159

mariadb

  • [mariadb] [bug] [dml] [mysql]

    修复了 MySQL 语句编译器无法正确编译 Insert.on_duplicate_key_update() 传递了包含 ORM 映射属性(例如 InstrumentedAttribute 对象)作为键的值的语句的错误。感谢 mingyu 的 pull request。

    参考: #12117

sqlite

2.0.37

已发布: 2025 年 1 月 9 日

orm

  • [orm] [bug]

    修复了 registry.type_annotation_mapUnion 类型中存在的问题,registry 或声明性基类,其中包含 Union 中存在的子类型之一的 Mapped 元素将与该条目匹配,可能忽略完全匹配的其他条目。现在执行正确的行为,使得条目应仅在 registry.type_annotation_map 中完全匹配,因为 Union 类型是一个自包含类型。例如,具有 Mapped[float] 的属性以前会匹配到 registry.type_annotation_map 条目 Union[float, Decimal];这将不再匹配,现在只会匹配到声明 float 的条目。感谢 Frazer McLean 的 pull request。

    参考: #11370

  • [orm] [bug]

    修复了类型联合在 registry.type_annotation_map 以及 Mapped 中的处理方式中的错误,这使得 a | b 的查找行为与 Union[a, b] 的查找行为不同。

    参考: #11944

  • [orm] [bug]

    一致地处理使用 python 3.12 中引入的 type X = int 语法获得的 TypeAliasType(在 PEP 695 中定义)。现在,在所有情况下,都必须将一个这样的别名显式添加到类型映射中,才能在 Mapped 内部使用它。此更改还修改了在 #11305 中添加的方法,现在需要将 TypeAliasType 添加到类型映射中。关于 SQLAlchemy 如何处理联合和类型别名类型的文档已添加到文档的 自定义类型映射 部分。

    参考: #11955

  • [orm] [bug]

    修复了最近 Mypy 版本响应的内部代码更改导致的回归,该回归导致传递给 ColumnOperators.in_() 的 ORM 映射属性表达式列表的非常不寻常的情况不再被接受。

    参考: #12019

  • [orm] [bug]

    修复了 registry.type_annotation_map 功能中类型处理的问题,这些问题阻止了在 future annotations 模式下使用联合(使用 pep-604 或 Union 语法),其中包含作为元素且可正确解析的多个泛型类型。

    参考: #12207

  • [orm] [bug]

    修复了事件系统中的问题,该问题阻止了事件侦听器从多个类对象(即分配给 Session 子类的 sessionmakerscoped_session 目标)附加和分离。

    参考: #12216

sql

  • [sql] [bug]

    修复了 “lambda SQL” 功能中的问题,其中如果跨多个编译阶段评估同一 lambda,包括跨多个引擎实例或禁用语句缓存时,绑定参数的跟踪可能会损坏。

    参考: #12084

postgresql

  • [postgresql] [usecase]

    Range 类型现在支持 Range.__contains__()。感谢 Frazer McLean 的 pull request。

    参考: #12093

  • [postgresql] [bug]

    修复了 PostgreSQL 方言中 Dialect.get_multi_indexes() 中的问题,其中尝试将 Alembic 与 pgvecto.rs 扩展中的向量索引一起使用时会引发错误。

    参考: #11724

  • [postgresql] [bug]

    修复了使用 asyncpg 驱动程序创建具有 SmallInteger 主列的表将导致类型编译为 SERIAL 而不是 SMALLSERIAL 的问题。

    参考: #12170

  • [postgresql] [bug]

    调整了 asyncpg 方言,以便可以在方言级别成功处理对于 PostgreSQL 服务器有效的空 SQL 字符串,例如在使用 Connection.exec_driver_sql() 时。感谢 Andrew Jackson 的 pull request。

    参考: #12220

mysql

  • [mysql] [usecase] [mariadb]

    为 MySQL 和 MariaDB 方言的 DELETE 添加了对 LIMIT 子句的支持,以补充已存在的 UPDATE 选项。Delete.with_dialect_options() 构造的方法接受 mysql_limitmariadb_limit 的参数,允许用户指定删除的行数限制。感谢 Pablo Nicolás Estevez 的 pull request。

    参考: #11764

  • [mysql] [bug] [mariadb]

    添加了逻辑,以确保 Update.with_dialect_options()Delete.with_dialect_options()mysql_limitmariadb_limit 参数在编译为字符串时,仅在参数作为整数传递时才编译;否则会引发 ValueError

mariadb

  • [mariadb] [usecase]

    在 MariaDB 方言中添加了 sql 类型 INET4INET6。感谢 Adam Žurek 的 pull request。

    参考: #10720

sqlite

  • [sqlite] [usecase]

    添加了 SQLite 表选项以启用 STRICT 表。感谢 Guilherme Crocetti 的 pull request。

    参考: #7398

oracle

  • [oracle] [feature]

    添加了新的表选项 oracle_tablespace,以在 Oracle 中创建表时指定 TABLESPACE 选项。这允许用户定义应在其中创建表的表空间。感谢 Miguel Grillo 的 pull request。

    参考: #12016

  • [oracle] [usecase]

    在确定 Oracle 方言中的标识符长度时,使用 oracledb 2.5 版本以来可用的连接属性 max_identifier_length

    参考: #12032

  • [oracle] [bug]

    修复了在 Oracle 数据库方言的 FROM 子句中使用 TABLE 函数时的编译问题。

    参考链接:#12100

  • [oracle] [bug]

    修复了 oracledb / cx_oracle 方言中的问题,即 CLOB 的输出类型处理器被路由到 NVARCHAR 而不是 VARCHAR,导致发生双重转换。

    参考链接:#12150

2.0.36

发布日期:2024 年 10 月 15 日

orm

  • [orm] [usecase]

    为 ORM 构造(如 sqlalchemy.orm.mapped_column(), sqlalchemy.orm.relationship() 等)添加了新的参数 mapped_column.hash。对于 ORM 原生数据类,此参数的解释方式与其他数据类特定的字段参数相同。

    参考链接:#11923

  • [orm] [bug]

    修复了 ORM 批量更新/删除中的错误,即在批量更新/删除中使用 RETURNING 并结合 populate_existing 时,无法适应 populate_existing 选项。

    参考链接:#11912

  • [orm] [bug]

    延续 #11912,即使语句未使用 RETURNING 或 populate_existing,当运行带有 WHERE 条件的 ORM 启用的 UPDATE 时,标有 mapped_column.onupdate, mapped_column.server_onupdateComputed 的列现在也会在 ORM 实例中刷新。

    参考链接:#11917

  • [orm] [bug]

    修复了 2.0.31 版本中 #11449 中对连接迫切加载的修复引起的回归,其中特定的 joinedload 情况无法正确断言。我们现在有了该情况的示例,因此断言已修复以允许这种情况。

    参考链接:#11965

  • [orm] [bug]

    改进了在尝试将类映射为数据类,同时手动提供 __table__ 属性时发出的错误消息。目前不支持此用法。

    参考链接:#11973

  • [orm] [bug]

    优化了 ORM 惰性加载器用于检测“这将通过主键加载,但主键为 NULL,跳过加载”的检查,以考虑 Mapper.allow_partial_pks 参数的当前设置。如果此参数为 False,则也应跳过具有部分 NULL 元素的复合主键值。这可能适用于某些复合重叠外键配置。

    参考链接:#11995

  • [orm] [bug]

    修复了 ORM “带有 WHERE 子句的更新”功能中的错误,其中显式的 .returning() 会干扰 “fetch” 同步策略,原因是假设 ORM 映射类在 RETURNING 中以特定位置为特征,包含主键列。此问题已修复,使用适当的 ORM 列目标。

    参考链接:#11997

sql

  • [sql] [usecase]

    当调用 TypeEngine.as_generic() 方法时,二进制类型(如 VARBINARY)将解析为 LargeBinary

    参考链接:#11978

  • [sql] [bug] [regression]

    修复了 1.4 版本中的回归,其中某些数据类型(如从 TypeDecorator 派生的数据类型)由于内部支持结构本身不可 pickle 化,因此在作为较大的 SQL 表达式组合的一部分时无法被 pickle 化。

    参考链接:#12002

schema

  • [schema] [bug]

    修复了传递给 Column.server_default 的 SQL 函数不会使用较新版本的 MySQL 和 MariaDB 现在要求的特定形式的括号呈现的错误。感谢 huuya 提供的 Pull request。

    参考链接:#11317

postgresql

  • [postgresql] [bug] [reflection]

    修复了表注释反射中的错误,如果 pg_description 表中的条目恰好与被反射的表共享相同的 oid (objoid),则会返回不相关的文本。

    参考链接:#11961

  • [postgresql] [bug]

    JSONJSONB 数据类型现在将在所有情况下为所有 PostgreSQL 后端(包括 psycopg2)呈现 “bind cast”,而之前仅为某些后端启用。这提高了数据库服务器识别何时将字符串值解释为 JSON 的准确性。

    参考链接:#11994

mysql

  • [mysql] [performance]

    改进了在反射外键时用于 MySQL 8 后端的查询,以进行更好的优化。以前,对于在所有表中有数百万列的数据库,该查询可能速度非常慢;该查询已重新设计,以更好地利用现有索引。

    参考链接:#11975

2.0.35

发布日期:2024 年 9 月 16 日

orm

  • [orm] [bug] [typing]

    修复了在 Python 3.8 和 3.9 上无法将 typing.LiteralMapped[] 一起使用的问题。感谢 Frazer McLean 提供的 Pull request。

    参考链接:#11820

  • [orm] [bug]

    修复了 ORM 求值器中的问题,即使用 SQL 连接运算符求值的两个数据类型不会根据其数据类型检查 UnevaluatableError;这遗漏了在连接操作中使用 JSONB 值的情况,PostgreSQL 支持此操作以及 SQLAlchemy 如何为此操作呈现 SQL,但这在 Python 级别不起作用。通过为此组合实现 UnevaluatableError,当 SET 子句中使用的连接 JSON 值要同步到 Python 对象时,ORM update 语句现在将回退到 “expire”。

    参考链接:#11849

  • [orm] [bug]

    如果 joinedload()subqueryload() 用作针对非 SELECT 语句(例如带有 insert().returning() 的语句)的顶级选项,则会发出警告。INSERT 语句中没有 JOIN,也没有可以重新用于子查询迫切加载的 “子查询”,并且对于 UPDATE/DELETE,joinedload 也不支持这些,因此在这种用法中静默传递永远是不合适的。

    参考链接:#11853

  • [orm] [bug]

    修复了将加载器选项(如 selectinload())与附加条件结合使用 ORM DML(如带有 RETURNING 的 insert())时,无法正确设置缓存正常工作所需的内部上下文,从而导致结果不正确的问题。

    参考链接:#11855

mysql

  • [mysql] [bug]

    修复了 mariadbconnector 方言中的问题,其中未检查整数或布尔参数的查询字符串参数将被忽略,例如字符串参数(如 unix_socket 等)。作为此更改的一部分,特定元素(如 client_flags, compress, local_infile)的参数解析在接受每个参数的所有 MySQL / MariaDB 方言中变得更加一致。感谢 Tobias Alex-Petersen 提供的 Pull request。

    参考链接:#11870

sqlite

  • [sqlite] [bug] [regression]

    版本 2.0.33 和 2.0.34 中针对 SQLite CHECK 约束反射所做的更改,#11832#11677,现已完全回退,因为用户继续识别出在此更改后停止工作的现有用例。目前,由于 SQLite 没有提供任何一致的方式来传递有关 CHECK 约束的信息,因此 SQLAlchemy 在可以反射的 CHECK 约束语法方面受到限制,包括 CHECK 约束必须全部在单个独立行(或列定义中的内联)中声明,约束定义中没有换行符、制表符,约束名称中也没有不寻常的字符。总的来说,SQLite 的反射是为能够反射最初由 SQLAlchemy DDL 构造创建的 CREATE TABLE 语句而量身定制的。长期来看,不依赖正则表达式的 DDL 解析器可能会最终改善这种情况。已经添加了广泛的跨方言 CHECK 约束反射测试,因为这些更改没有触发任何现有测试也是一个错误。

    参考链接:#11840

2.0.34

发布日期:2024 年 9 月 4 日

orm

  • [orm] [bug]

    修复了问题 #11814 引起的回归,该问题破坏了对某些 PEP 593 Annotated 风格的支持,当在 type_annotation_map 中使用诸如 list, dict 等内置类型而没有元素类型时。虽然这是一种不完整的类型风格,但这些类型仍然会正确地位于 type_annotation_map 中。

    参考链接:#11831

sqlite

  • [sqlite] [bug]

    修复了 #11677 引起的 SQLite 反射回归,该回归干扰了对 CHECK 约束的反射,而 CHECK 约束之后是同一表定义中的其他类型的约束。感谢 Harutaka Kawamura 提供的 Pull request。

    参考链接:#11832

2.0.33

发布日期:2024 年 9 月 3 日

general

  • [general] [change]

    pyproject.tomlsetuptools<69.3 的 pin 已被移除。此 pin 是为了防止 setuptools 突然更改为使用 PEP 625,这将更改 SQLAlchemy 源代码发行版在 pypi 上的文件名为全小写名称,这可能会给各种期望先前命名样式的构建环境带来问题。但是,此 pin 的存在正在阻碍其他想要使用较新 setuptools 的环境,因此我们已决定继续进行此更改,并假设构建环境现在已在很大程度上适应了 setuptools 更改。

    参考链接:#11818

orm

  • [orm] [bug] [regression]

    修复了从 1.3 版本开始的回归,其中混合属性的列键可能会填充其返回的基础列的列键,对于直接返回 ORM 映射列的属性,而不是混合属性本身使用的键。

    此更改也已向后移植到:1.4.54

    参考链接:#11728

  • [orm] [bug]

    当没有内部模块或类注册到内部顶级模块注册表时,正确清理内部顶级模块注册表。

    参考链接:#11788

  • [orm] [bug]

    改进了 ORM 注解声明类型映射查找,处理组合类型,例如链接到 JSON(或其他)的 dict[str, Any],无论是否处于 “future annotations” 模式。

    参考链接:#11814

engine

  • [engine] [bug]

    修复了内部反射缓存中的问题,其中关于同名 quoted_name() 构造的特定反射场景无法正确缓存。感谢 Felix Lüdin 提供的 Pull request。

    参考链接:#11687

sql

  • [sql] [bug] [regression]

    修复了 Select.with_statement_hint() 和其他方法中的回归,其中该方法的生成行为停止生成对象的副本。

    参考链接:#11703

schema

  • [schema] [bug]

    修复了 Enum 数据类型的 metadata 元素在通过 Table.to_metadata() 操作复制类型时,不会传输到新的 MetaData 对象,从而导致创建/删除序列中行为不一致的错误。

    参考链接:#11802

typing

postgresql

  • [postgresql] [bug]

    修复了 asyncpg 驱动程序中的严重问题,其中专门针对 MissingGreenlet 条件或任何其他非 asyncpg 本身引发的错误而失败的回滚或提交,在任何情况下都会丢弃 asyncpg 事务,即使事务仍然空闲,从而导致服务器端条件出现空闲事务,然后该事务返回到连接池。现在,对于 asyncpg 本身之外引发的错误,不会重置 “事务已关闭” 标志。当 asyncpg 本身针对 .commit().rollback() 引发错误时,asyncpg 确实会丢弃此事务。

    此更改也已向后移植到:1.4.54

    参考链接:#11819

  • [postgresql] [bug]

    修订了首次在 #10717 中进行的 asyncpg terminate() 修复,该修复提高了在所有情况下此调用的弹性,将 asyncio.CancelledError 添加到被拦截为优雅 .close() 失败的异常列表中,然后将继续调用 .terminate()

    参考链接:#11821

mysql

  • [mysql] [bug]

    修复了 MySQL 方言中的问题,其中将 INSERT..FROM SELECT 与 ON DUPLICATE KEY UPDATE 结合使用会在 MySQL 8 及更高版本上错误地呈现 “AS new” 子句,从而导致语法失败。如果使用了 “new” 别名,则 MySQL 8 上需要此子句来跟随 VALUES 子句,但不允许跟随 FROM SELECT 子句。

    参考链接:#11731

sqlite

  • [sqlite] [bug]

    改进了 SQLite 方言用于反射 CHECK 约束的名称和内容的正则表达式。现在可以正确反射约束文本和约束名称中包含换行符、制表符或空格字符的约束。感谢 Jeff Horemans 提供的 Pull request。

    参考链接:#11677

  • [sqlite] [bug]

    改进了 SQLite 方言用于反射在 SQLite CREATE TABLE 语句的列定义内内联定义的 UNIQUE 约束的名称和内容的正则表达式,以适应列/约束行中存在的制表符。感谢 John A Stevenson 提供的 Pull request。

    参考链接:#11746

mssql

  • [mssql] [bug]

    将错误 “服务器无法恢复事务” 添加到 pymssql 驱动程序中用于确定断开连接场景的错误字符串列表中,正如一位用户在其他未知条件下使用 pymssql 时观察到的那样,这会在连接池中留下无法使用的连接,从而无法干净地 ping 通。

    参考链接:#11822

tests

  • [tests] [bug]

    为测试套件 SuiteRequirements 类添加了缺少的 array_type 属性。

2.0.32

发布日期:2024 年 8 月 5 日

general

orm

  • [orm] [usecase]

    aliased.name 参数现在可以与 aliased.flat 参数结合使用,从而基于名称前缀命名约定生成每个表的名称。感谢 Eric Atkin 提供的 Pull request。

    参考链接:#11575

  • [orm] [bug] [regression]

    修复了追溯到 1.4 版本的回归,其中在瞬态对象上使用 “dynamic” 策略访问集合并尝试查询会引发内部错误,而不是 1.3 版本中发生的预期 NoResultFound

    此更改也已向后移植到:1.4.53

    参考链接:#11562

  • [orm] [bug]

    修复了同时使用 Query.enable_eagerloads()Query.yield_per() 方法,以便禁用直接在映射器上配置的迫切加载,会被静默忽略,从而导致错误或属性的意外迫切填充。

    参考链接:#10834

  • [orm] [bug] [regression]

    修复了 2.0.21 版本中出现的回归问题,该问题由 #10279 引起。当对继承层次结构基类的 ORM 类使用 delete()update(),同时指定应以多态方式加载子类时,会导致多态连接泄漏到 UPDATE 或 DELETE 语句中,从而创建不正确的 SQL。

    参考链接:#11625

  • [orm] [bug] [regression]

    修复了 1.4 版本中 Session.bulk_insert_mappings() 的回归问题,其中使用 Session.bulk_insert_mappings.return_defaults 参数不会用新生成的主键值填充传入的字典。

    参考链接:#11661

  • [orm]

    添加了一个警告,指出 ConnectionEvents.engine_connect() 事件可能正在遗留一个打开的事务,这可能会改变使用此类引擎作为绑定的 Session 的行为。在 SQLAlchemy 2.1 中,当会话绑定是 Engine 时,Session.join_transaction_mode 将在所有情况下被忽略。

    参考链接:#11163

示例

  • [examples] [bug]

    修复了 history_meta 示例中的问题,其中版本化表中的 “version” 列需要在 INSERT 时默认为历史表中的最新版本号,以适应表中的行被删除,然后可以被重用相同主键标识的新行替换的用例。此修复为主要表中的每个 INSERT 添加了一个额外的 SELECT 查询,这可能效率低下;对于不重用主键的情况,可以省略默认函数。补丁由 Philipp H. v. Loewenfeld 提供。

    参考链接:#10267

引擎

  • [engine] [bug]

    修复了 “insertmanyvalues” 功能中的问题,其中对 cursor.fetchall() 的特定调用未包含在 SQLAlchemy 的异常包装器中,这显然在使用 pyodbc 时可能会在提取期间引发数据库异常。

    参考链接:#11532

SQL

  • [sql] [bug]

    跟进 #11471 以修复缓存问题,其中使用 CompoundSelectState.add_cte() 方法的 CompoundSelectState 构造不会设置正确的缓存键,该缓存键区分不同的 CTE 表达式。还添加了可以检测与 #11544 中修复的问题类似的问题的测试。

    参考链接:#11471

  • [sql] [bug]

    修复了 Operators.nulls_first()Operators.nulls_last() 修饰符在确定 ORDER BY 是否应针对语句中已有的标签名称时,不会像 Operators.desc()Operators.asc() 一样处理的错误。现在,所有四个修饰符在 ORDER BY 中都被同等对待。

    参考链接:#11592

模式

  • [schema] [bug]

    修复了由 Enum 数据类型的反序列化触发的事件系统中的其他问题,延续了 #11365#11360,其中在新进程中反序列化时,事件结构的动态生成元素将不会存在。

    参考链接:#11530

类型标注

  • [typing] [bug]

    修复了内部类型标注问题,以建立与 mypy 1.11.0 的兼容性。请注意,这不包括使用 SQLAlchemy 1.4 风格代码的已弃用 mypy 插件出现的问题;请参阅此插件的其他更改说明,其中指出了修订后的兼容性。

mypy

  • [mypy] [bug]

    已弃用的 mypy 插件不再完全兼容最新的 mypy 1.11.0 系列,因为 mypy 解释器中的更改不再与插件使用的方法兼容。如果代码依赖于带有 sqlalchemy2-stubs 的 mypy 插件,建议将 mypy 版本锁定在 1.11.0 系列以下。请考虑升级到 SQLAlchemy 2.0 系列并迁移到现代类型注解。

    此更改也已向后移植到:1.4.53

postgresql

  • [postgresql] [bug]

    当 psycopg2 抛出 “SSL SYSCALL error: Success” 错误消息时,现在被认为是池失效的断开连接事件,当到 Postgres 的 SSL 连接异常终止时可能会发生这种情况。

    参考链接:#11522

  • [postgresql] [bug]

    修复了 collate() 构造的问题,该构造显式地为给定表达式设置排序规则,会为表达式中的底层类型对象维护排序规则设置,导致 SQL 表达式在用于进一步表达式时同时声明两个排序规则,对于呈现显式类型转换的特定方言(例如 asyncpg)而言。 collate() 构造现在为其自身类型分配排序规则,以显式包含新的排序规则,假设它是一个字符串类型。

    参考链接:#11576

mysql

  • [mysql] [bug]

    修复了 MySQL 方言中包含百分号的 ENUM 值未正确转义以供驱动程序使用的问题。

    参考链接:#11479

sqlite

  • [sqlite] [bug] [reflection]

    修复了 SQLite 中计算列的反射,以正确处理复杂表达式。

    此更改也已向后移植到:1.4.53

    参考链接:#11582

mssql

  • [mssql] [bug]

    修复了 SQL Server 驱动程序在呈现窗口函数的 “frame specification”(例如 “ROWS BETWEEN” 等)时不支持绑定参数的问题。

    此更改也已向后移植到:1.4.53

    参考链接:#11514

oracle

  • [oracle] [usecase]

    为 oracledb 异步方言添加了服务器端游标的 API 支持,允许使用 AsyncConnection.stream() 和类似的流方法。

    参考链接:#10820

  • [oracle] [usecase]

    为 oracledb 方言实现了两阶段事务。从历史上看,此功能从未与 cx_Oracle 方言一起使用,但 oracledb 后续版本的最新改进现在使其成为可能。两阶段事务 API 可在 Core 级别通过 Connection.begin_twophase() 方法获得。

    参考链接:#11480

  • [oracle] [bug]

    修复了 Oracle 10.2 及更早版本上的表反射,其中不支持压缩选项。

    参考链接:#11557

  • [oracle] [bug] [sqlite]

    为 Oracle 实现了按位运算符,由于此数据库使用的非标准语法,该运算符以前无法正常工作。Oracle 对按位 “或” 和 “异或” 的支持从服务器版本 21 开始。此外,修复了 SQLite 中 “异或” 的实现。

    作为此更改的一部分,方言合规性测试套件已得到增强,以包括对服务器端按位测试的支持;第三方方言作者应参考 requirements.py 文件中的新 “supports_bitwise” 方法来启用这些测试。

    参考链接:#11663

2.0.31

发布日期:2024 年 6 月 18 日

通用

  • [general] [bug]

    设置了全面的 Python 3.13 支持,目前在最大程度上修复了内部语言助手以及序列化程序扩展模块中的问题。

    对于 1.4 版本,这也使 setup.cfg 中的 “extras” 名称现代化,对于两个词的名称使用短划线而不是下划线。下划线名称仍然存在,以适应潜在的兼容性问题。

    此更改也已向后移植到:1.4.53

    参考链接:#11417

  • [general] [bug]

    设置了全面的 Python 3.13 支持,目前在最大程度上修复了内部语言助手以及序列化程序扩展模块中的问题。

    参考链接:#11417

ORM

  • [orm] [usecase]

    添加了缺少的参数 with_polymorphic.name,该参数允许指定返回的 AliasedClass 的名称。

    参考链接:#11361

  • [orm] [bug]

    修复了如果存在已适配的 EnumBoolean 数据类型,MetaData 集合将不可序列化的问题。当在 ORM 注解声明形式中使用 EnumBoolean 时,可能会发生此特定场景,其中类型对象经常被复制。

    参考链接:#11365

  • [orm] [bug]

    修复了当针对本身包含子类特定 Mapper.with_polymorphic 设置的继承子类进行 selectinload()subqueryload() 加载器选项时,这些选项将无法生效的问题。

    参考链接:#11446

  • [orm] [bug]

    修复了一个非常古老的问题,该问题涉及 joinedload.innerjoin 参数,其中使用此参数混入也包含沿自引用或其他循环关系的连接急切加载的查询,以及诸如为辅助表添加的内连接之类的复杂因素,可能会将特定的内连接拼接错误到查询的错误部分。已向执行此拼接的内部方法添加了其他状态,以便更好地决定应在何处进行拼接。

    参考链接:#11449

  • [orm] [bug] [regression]

    修复了 ORM 声明式中的错误,其中 __table__ 指令无法在超类上声明为带有 declared_attr() 的类函数,包括 __abstract__ 类以及来自声明式基类本身的情况。这是自 1.4 以来的回归问题,当时这是有效的,并且显然没有针对此特定用例的测试。

    参考链接:#11509

引擎

  • [engine] [usecase]

    修改了用于调整 asyncio 调用到 greenlet 的内部表示形式,以允许与直接实现 SQLAlchemy 的 “greenlet-to-asyncio” 模式的第三方库进行鸭子类型兼容性。在具有属性 __sqlalchemy_greenlet_provider__ = True 的 greenlet 中运行代码将允许直接调用 sqlalchemy.util.await_only()

    此更改也已向后移植到:1.4.53

SQL

模式

mysql

  • [mysql] [usecase] [reflection]

    在 MySQL 和 MariaDB 方言中添加了缺少的外部键反射选项 SET DEFAULT。拉取请求由 Quentin Roche 提供。

    参考链接:#11285

2.0.30

发布日期:2024 年 5 月 5 日

ORM

引擎

  • [engine] [bug]

    修复了 Connection.execution_options.logging_token 选项中的问题,其中更改已记录消息的连接上的 logging_token 值将不会更新以反映新的日志记录令牌。特别是,这阻止了使用 Session.connection() 更改连接上的选项,因为 BEGIN 日志记录消息已经发出。

    参考链接:#11210

  • [engine] [bug]

    修复了游标处理中的问题,该问题影响了在 select() 的 columns 子句中处理重复的 Column 或类似对象,无论是否与 SELECT 列表中的任意 text() 子句组合使用,以及尝试检索对象的 Result.mappings() 时,这都会导致内部错误。

    参考: #11306

typing

  • [类型提示] [错误] [回归]

    修复了版本 2.0.29 中由 #11055 引起的类型提示回归,该回归为 asyncio run_sync() 方法添加了 ParamSpec,其中使用 AsyncConnection.run_sync()MetaData.reflect() 会由于 mypy 问题而在 mypy 上失败。感谢 Francisco R. Del Roio 提供 Pull request。

    参考: #11200

  • [类型提示] [错误]

    修复了 Bundle 的类型提示问题,其中不允许创建嵌套的 Bundle 结构。

misc

  • [错误] [测试]

    确保在使用 subprocess.run 进行测试时,PYTHONPATH 变量已正确初始化。

    参考: #11268

  • [错误] [安装]

    修复了一个内部类,该类旨在测试即将到来的 Python 3.13 下的意外属性,使其能够正常工作。感谢 Edgar Ramírez-Mondragón 提供 Pull request。

    参考: #11334

2.0.29

发布日期:2024 年 3 月 23 日

orm

  • [ORM] [用例]

    添加了对 PEP 695 TypeAliasType 构造以及 python 3.12 原生 type 关键字的支持,以便在使用这些构造链接到 PEP 593 Annotated 容器时,能够与 ORM Annotated Declarative 形式一起使用,从而允许在 Mapped 类型容器中使用这些构造时解析 Annotated

    参考: #11130

  • [ORM] [错误]

    修复了 Declarative 问题,其中使用 Relationship 而不是 Mapped 对关系进行类型提示会无意中为该属性引入 “dynamic” 关系加载器策略。

    参考: #10611

  • [ORM] [错误]

    修复了 ORM annotated declarative 中的问题,其中将 mapped_column()mapped_column.indexmapped_column.unique 设置为 False 会被传入的 Annotated 元素覆盖,即使该参数设置为 True,即使直接的 mapped_column() 元素更具体,应该优先。增强了协调布尔值的逻辑,以适应本地值为 False 的情况,使其仍然优先于来自 annotated 元素的传入 True 值。

    参考: #11091

  • [ORM] [错误] [回归]

    修复了版本 2.0.28 中由 #11085 的修复引起的回归,其中调整后缓存绑定参数值的新方法会干扰 subqueryload() 加载器选项的实现,当附加加载器条件功能与此加载器选项一起使用时,该选项在内部使用了一些更旧的模式。

    参考: #11173

engine

  • [引擎] [错误]

    修复了 INSERT 语句的 “Insert Many Values” 行为 功能中的问题,其中使用带有 “inline execute” 默认生成器(例如带有显式 schema 名称的显式 Sequence)的主键列,同时使用 Connection.execution_options.schema_translate_map 功能将无法正确呈现序列或参数,从而导致错误。

    参考: #11157

  • [引擎] [错误]

    对版本 2.0.10 中为 #9618 所做的调整进行了更改,该调整添加了将批量 INSERT 的 RETURNING 行与传递给它的参数进行协调的行为。此行为包括将已转换为数据库的绑定参数值与返回的行值进行比较,对于诸如 UUID 之类的 SQL 列类型,这种比较并不总是 “对称” 的,具体取决于不同的 DBAPI 如何接收此类值以及如何返回它们,因此需要在这些列类型上使用额外的 “sentinel 值解析器” 方法。不幸的是,这破坏了第三方列类型,例如 SQLModel 等库中的 UUID/GUID 类型,这些类型未实现此特殊方法,从而引发错误 “Can’t match sentinel values in result set to parameter sets”。与其尝试进一步解释和记录 “insertmanyvalues” 功能的此实现细节,包括新方法的公共版本,不如修改方法,不再需要此额外的转换步骤,并且执行比较的逻辑现在在预转换的绑定参数值与后结果处理的值之间工作,这应该始终是匹配的数据类型。在不寻常的情况下,自定义 SQL 列类型也恰好在批量 INSERT 的 “sentinel” 列中使用,并且没有接收和返回相同的值类型,则会引发 “Can’t match” 错误,但是缓解措施很简单,即应传递与返回类型相同的 Python 数据类型。

    参考: #11160

sql

  • [SQL] [错误] [回归]

    修复了 1.4 系列的回归,其中 TypeEngine.with_variant() 方法在 “with_variant()” 克隆原始 TypeEngine 而不是更改类型 中引入的重构未能适应 .copy() 方法,这将丢失已设置的 variant 映射。这对于 “schema” 类型的非常特殊的情况成为一个问题,其中包括诸如 EnumARRAY 之类的类型,当它们在 ORM Declarative 映射中与 mixin 一起使用时,类型的复制就会发挥作用。variant 映射现在也已复制。

    参考: #11176

typing

  • [类型提示] [错误]

    修复了类型提示问题,允许 asyncio run_sync() 方法根据传递的可调用对象正确键入参数,从而利用 PEP 612 ParamSpec 变量。感谢 Francisco R. Del Roio 提供 Pull request。

    参考: #11055

postgresql

  • [PostgreSQL] [用例]

    PostgreSQL 方言现在在反射类型为 domain 的列时返回 DOMAIN 实例。以前,返回的是 domain 数据类型。作为此更改的一部分,domain 反射得到了改进,也返回了文本类型的排序规则。感谢 Thomas Stephenson 提供 Pull request。

    参考: #10693

tests

  • [测试] [错误]

    向 SQLAlchemy 2.0 反向移植了测试套件的改进,关于如何运行 asyncio 相关测试,现在使用较新的 Python 3.11 asyncio.Runner 或反向移植的等效项,而不是依赖于以前基于 asyncio.get_running_loop() 的实现。这应该有望防止在 CPU 负载过重的硬件上运行大型套件时出现问题,在这种情况下,事件循环似乎会损坏,从而导致级联故障。

    参考: #11187

2.0.28

发布日期:2024 年 3 月 4 日

orm

  • [ORM] [错误] [回归]

    修复了由 #9779 引起的回归,其中在关系 and_() 表达式中使用 “secondary” 表会导致别名失败,无法与 “secondary” 表在 Select.join() 表达式中正常呈现的方式相匹配,从而导致无效查询。

    参考: #11010

  • [ORM] [错误] [性能] [回归]

    调整了在 #10570 中所做的修复,该修复在 2.0.23 中发布,其中添加了新逻辑来协调 with_expression() 构造中使用的缓存键生成中可能更改的绑定参数值。新逻辑更改了将新绑定参数值与语句关联的方法,避免了需要深度复制语句,这可能会导致非常深/复杂的 SQL 构造的性能显着下降。新方法不再需要此深度复制步骤。

    参考: #11085

engine

asyncio

tests

  • [测试] [更改]

    tox.ini 文件中的 pytest 支持已更新,以支持 pytest 8.1。

2.0.27

发布日期:2024 年 2 月 13 日

postgresql

  • [PostgreSQL] [错误] [回归]

    修复了刚刚发布的 #10863 修复引起的回归,其中在 “except” 块中添加了无效的异常类,除非实际发生此类捕获,否则不会执行该块。已添加 mock 样式的测试,以确保在单元测试中执行此捕获。

    参考: #11005

2.0.26

发布日期:2024 年 2 月 11 日

orm

  • [ORM] [错误]

    对于由于加载器选项链太深而导致 ORM 禁用缓存的语句,将 “加载器深度过深” 警告替换为添加到 SQL 日志记录中缓存徽章的较短消息。此警告突出显示的条件难以解决,通常只是 ORM 应用 SQL 缓存的限制。未来的功能可能包括调整禁用缓存的阈值的能力,但目前该警告将不再令人讨厌。

    参考: #10896

  • [ORM] [错误]

    修复了在 Mapped 容器类型中使用类型(例如 enum)时,如果该类型在类主体中本地声明,则无法使用的问题。用于 eval 的 locals 作用域现在包括类主体本身的作用域。此外,如果以字符串形式或使用 future annotations 模式使用,则 Mapped 中的表达式也可以引用类名本身。

    参考: #10899

  • [ORM] [错误]

    修复了在 Session.delete()Mapper.version_id_col 功能一起使用时,如果由于在对象上使用了 relationship.post_update 而对目标对象发出了额外的 UPDATE,则无法使用正确的版本标识符的问题。此问题与版本 2.0.25 中刚刚修复的仅更新案例 #10800 类似。

    参考: #10967

  • [ORM] [错误]

    修复了在 with_expression() 实现中的断言会在使用不可缓存的 SQL 表达式时引发的问题;这是自 1.4 以来的 2.0 回归。

    参考: #10990

examples

  • [示例] [错误]

    修复了 history_meta 示例中的回归,其中使用 MetaData.to_metadata() 复制历史表也会复制索引(这是一件好事),但会导致索引命名冲突,而与用于这些索引的命名方案无关。现在,向这些索引添加 “_history” 后缀,其方式与表名称的方式相同。

    参考: #10920

  • [示例] [错误]

    修复了 examples/performance 中的性能示例脚本,使其主要与 Oracle 数据库一起工作,方法是将 Identity 构造添加到所有表中,并允许在此后端上发生主键生成。一些 “raw DBAPI” 案例仍然与 Oracle 不兼容。

sql

  • [SQL] [错误]

    修复了 case() 中的问题,其中用于确定表达式类型的逻辑可能会导致 NullType,如果 “whens” 中的最后一个元素没有类型,或者在其他情况下,类型可能会解析为 None。逻辑已更新为扫描所有给定的表达式,以便使用第一个非空类型,并始终确保存在类型。感谢 David Evans 提供 Pull request。

    参考: #10843

typing

postgresql

  • [PostgreSQL] [用例] [反射]

    添加了对反射标记为 “NO INHERIT” 的 PostgreSQL CHECK 约束的支持,在反射数据中设置键 no_inherit=True。感谢 Ellis Valentiner 提供 Pull request。

    参考: #10777

  • [PostgreSQL] [用例]

    支持 PostgreSQL CREATE TABLEUSING <method> 选项,以指定用于存储新表内容的访问方法。感谢 Edgar Ramírez-Mondragón 提供 Pull request。

    另请参阅

    PostgreSQL 表选项

    参考: #10904

  • [PostgreSQL] [用例]

    将 PostgreSQL RANGE 和 MULTIRANGE 类型正确键入为 Range[T]Sequence[Range[T]]。引入了实用程序序列 MultiRange,以实现 MULTIRANGE 类型更好的互操作性。

    参考: #9736

  • [PostgreSQL] [用例]

    在从 RangeMultiRange 实例推断数据库类型时,区分 INT4 和 INT8 范围和多范围类型,如果值适合,则首选 INT4。

  • [PostgreSQL] [错误] [回归]

    修复了由 #10717 在版本 2.0.24 中引起的 asyncpg 方言的回归,其中现在尝试在终止之前优雅地关闭 asyncpg 连接的更改不会回退到 terminate() 以处理超时错误以外的其他潜在的连接相关异常,而没有考虑到优雅的 .close() 尝试由于连接错误等其他原因而失败的情况。

    参考: #10863

  • [PostgreSQL] [错误]

    修复了将 Uuid 数据类型与 Uuid.as_uuid 参数设置为 False 一起使用时,使用 PostgreSQL 方言时出现的问题。ORM 优化的 INSERT 语句(例如 “insertmanyvalues” 功能)将无法正确对齐批量 INSERT 语句的主键 UUID 值,从而导致错误。pymssql 驱动程序也修复了类似的问题。

mysql

  • [MySQL] [错误]

    修复了无法从也指定了 VIRTUAL 或 STORED 指令的 MySQL 列中正确反射 NULL/NOT NULL 的问题。感谢 Georg Wicke-Arndt 提供 Pull request。

    参考: #10850

  • [MySQL] [错误]

    修复了 asyncio 方言 asyncmy 和 aiomysql 中的问题,它们的 .close() 方法显然不是优雅的关闭。替换为非标准的 .ensure_closed() 方法,该方法是可等待的,并将 .close() 移动到所谓的 “terminate” 情况。

    参考: #10893

mssql

  • [MSSQL] [错误]

    修复了在使用 pymssql 方言时,当 Uuid 数据类型的 Uuid.as_uuid 参数设置为 False 时出现的问题。ORM 优化的 INSERT 语句(例如 “insertmanyvalues” 功能)无法为批量 INSERT 语句正确对齐主键 UUID 值,从而导致错误。PostgreSQL 驱动程序也修复了类似的问题。

oracle

  • [oracle] [bug] [性能]

    更改了 Oracle 方言的默认 arraysize,以便使用驱动程序设置的值,即在编写本文时 cx_oracle 和 oracledb 的值均为 100。之前默认值设置为 50。与单独使用 cx_oracle/oracledb 获取数百行数据(通过较慢的网络)相比,设置为 50 可能会导致明显的性能下降。

    参考链接: #10877

2.0.25

发布日期:2024 年 1 月 2 日

orm

  • [orm] [usecase]

    添加了对 Python 3.12 pep-695 类型别名结构的初步支持,用于解析 ORM Annotated Declarative 映射的自定义类型映射。

    参考链接: #10807

  • [orm] [bug]

    修复了当同时使用 relationship.post_update 功能和 mapper version_id_col 时,可能导致 post-update 功能发出的第二个 UPDATE 语句无法使用正确的版本标识符的情况,假设在 flush 中已经发出了一个 UPDATE,该 UPDATE 已经增加了版本计数器。

    参考链接: #10800

  • [orm] [bug]

    修复了 ORM Annotated Declarative 会错误地将没有指定集合的关系的左侧解释为 uselist=True 的问题,如果左侧类型以类而不是字符串的形式给出,且未使用 future-style 注解。

    参考链接: #10815

sql

  • [sql] [bug]

    改进了在布尔比较的否定上下文中 any_() / all_() 的编译,现在将渲染 NOT (expr) 而不是反转相等运算符为不等于,从而允许对这些非典型运算符进行更细粒度的否定控制。

    参考链接: #10817

typing

  • [typing] [bug]

    修复了在 2.0.24 版本中添加到 sqlalchemy.sql.functions 模块的类型标注引起的回归问题,作为 #6810 的一部分。

    • 进一步增强了 pep-484 类型标注,允许来自 sqlalchemy.sql.expression.func 派生的 SQL 函数元素更有效地与 ORM 映射属性一起使用 (#10801)

    • 修复了传递给函数的参数类型,以便字符串和整数等字面表达式再次被正确解释 (#10818)

    参考链接: #10801, #10818

asyncio

  • [asyncio] [bug]

    修复了连接池 asyncio 版本中的一个严重问题,即调用 AsyncEngine.dispose() 会产生一个新的连接池,该连接池没有完全重新建立 asyncio 兼容的互斥锁的使用,导致使用了普通的 threading.Lock(),然后在 asyncio 上下文中使用 asyncio.gather() 等并发功能时会导致死锁。

    此更改也已向后移植到:1.4.51

    参考链接: #10813

oracle

  • [oracle] [asyncio]

    在使用新发布的 oracledb DBAPI 版本(包含 asyncio 支持)的 asyncio 模式下,添加了对 python-oracledb 的支持。对于 2.0 系列,这是一个预览版本,当前实现尚不支持 AsyncConnection.stream()。计划在 SQLAlchemy 2.1 版本中改进支持。

    参考链接: #10679

2.0.24

发布日期:2023 年 12 月 28 日

orm

  • [orm] [bug]

    改进了版本 0.9.8 中发布的 #3208 的首次修复,其中声明式内部使用的类注册表可能会受到竞争条件的影响,当个别映射类在被垃圾回收的同时,新的映射类正在被构建时,就会发生这种情况,这可能发生在某些测试套件配置或动态类创建环境中。除了已经添加的 weakref 检查之外,迭代的项目列表也首先被复制,以避免 “迭代时列表已更改” 错误。感谢 Yilei Yang 提供的 pull 请求。

    此更改也已向后移植到:1.4.51

    参考链接: #10782

  • [orm] [bug]

    修复了在未初始化的 mapped_column() 构造上使用 foreign() 注解会产生没有类型的表达式的问题,这在实际列的初始化时没有被更新,从而导致诸如关系无法正确确定 use_get 等问题。

    参考链接: #10597

  • [orm] [bug]

    改进了当工作单元进程由于具有依赖规则的相关对象被删除而将主键列的值设置为 NULL 时产生的错误消息,使其不仅包含目标对象和列名,还包含 NULL 值来源的源列。感谢 Jan Vollmer 提供的 pull 请求。

    参考链接: #10668

  • [orm] [bug]

    修改了 MappedAsDataclass, DeclarativeBaseDeclarativeBaseNoMeta 使用的 __init_subclass__() 方法,以接受任意 **kw 并将其传播到 super() 调用,从而在安排使用 __init_subclass__() 关键字参数的自定义超类和 mixin 时提供更大的灵活性。感谢 Michael Oliver 提供的 pull 请求。

    参考链接: #10732

  • [orm] [bug]

    确保在 ORM 启用的 INSERT、UPDATE 和 DELETE 语句的 returning() 部分中使用的 Bundle 对象的使用案例经过测试并完全工作。这在之前从未明确实现或测试过,并且在 1.4 系列中无法正常工作;在 2.0 系列中,带有 WHERE 条件的 ORM UPDATE/DELETE 缺少一个实现方法,阻止了 Bundle 对象正常工作。

    参考链接: #10776

  • [orm] [bug]

    修复了 MutableList 中的 2.0 回归问题,其中检测序列的例程无法正确过滤掉字符串或字节实例,使得无法将字符串值分配给特定索引(而非序列值可以正常工作)。

    参考链接: #10784

engine

  • [engine] [bug]

    修复了使用 URL.render_as_string() 方法将 URL 对象转换为字符串时,用户名和密码组件的 URL 编码问题,通过使用 Python 标准库 urllib.parse.quote,同时允许加号和空格保持不变,这符合 SQLAlchemy 的非标准 URL 解析,而不是多年前遗留的自制例程。感谢 Xavier NUNN 提供的 pull 请求。

    参考链接: #10662

sql

  • [sql] [bug]

    修复了 SQL 元素的字符串化问题,当未传递特定方言时,如果遇到方言特定的元素(例如 PostgreSQL “on conflict do update” 构造),则无法为字符串化方言提供适当的状态来渲染该构造,从而导致内部错误。

    参考链接: #10753

  • [sql] [bug]

    修复了字符串化或编译 CTE(针对 DML 构造,例如 insert() 构造)会因错误检测到语句总体是 INSERT 而导致字符串化失败的问题,从而导致内部错误。

schema

  • [schema] [bug]

    修复了在创建 Table 等对象时,意外模式项的错误报告错误地处理了本身作为元组传递的参数的问题,导致格式化错误。错误消息已现代化为使用 f-strings。

    参考链接: #10654

typing

  • [typing] [bug]

    完成了 sqlalchemy.sql.functions 模块的 pep-484 类型标注。针对 func 元素进行的 select() 构造现在应该具有填充的返回类型。

    参考链接: #6810

asyncio

  • [asyncio] [change]

    async_fallback 方言参数现已弃用,将在 SQLAlchemy 2.1 中移除。此标志已有一段时间未在 SQLAlchemy 的测试套件中使用。asyncio 方言仍然可以通过使用 greenlet_spawn() 在 greenlet 中运行代码,以同步方式运行。

postgresql

  • [postgresql] [bug]

    调整了 asyncpg 方言,以便在使用 terminate() 方法丢弃无效连接时,如果操作在 async 事件循环上下文中进行,则方言将首先尝试使用带有超时时间的 .close() 优雅地关闭连接。这允许 asyncpg 驱动程序处理 TimeoutError 的最终确定,包括能够关闭长时间运行的服务器端查询,否则查询可能会在程序退出后继续运行。

    参考链接: #10717

mysql

  • [mysql] [bug]

    修复了在对 PyMySQL 1.0 之前的版本使用池预连接时,由 #10492 的修复引入的回归问题。

    此更改也已向后移植到:1.4.51

    参考链接: #10650

tests

  • [tests] [bug]

    改进了测试套件,以进一步加强其在未安装 Python greenlet 时运行的能力。现在有一个 tox 目标,其中包括 token “nogreenlet”,它将在未安装 greenlet 的情况下运行套件(请注意,它仍然作为 tox 配置的一部分临时安装 greenlet)。

    参考链接: #10747

2.0.23

发布日期:2023 年 11 月 2 日

orm

  • [orm] [usecase]

    为新的批量 ORM 插入实现了 Session.bulk_insert_mappings.render_nulls 参数,允许 render_nulls=True 作为执行选项。这允许在参数字典中混合使用 None 值的批量 ORM 插入,为给定的字典键集合使用单批行,而不是分成多批,每批都从 INSERT 中省略 NULL 列。

    参考链接: #10575

  • [orm] [bug]

    修复了 __allow_unmapped__ 指令未能允许遗留的 Column / deferred() 映射的问题,这些映射尽管如此,但仍具有诸如 Any 或不带 Mapped[] 的特定类型之类的注解,而没有与定位属性名称相关的错误。

    参考链接: #10516

  • [orm] [bug]

    修复了缓存错误,其中将 with_expression() 构造与加载器选项 selectinload(), lazyload() 结合使用会导致在后续缓存运行时无法正确替换绑定参数值。

    参考链接: #10570

  • [orm] [bug]

    修复了 ORM 注解声明式中的一个 bug,其中使用 ClassVar,但以某种方式引用了 ORM 映射的类名,则无法被解释为未映射的 ClassVar

    参考链接: #10472

sql

  • [sql] [usecase]

    为 PostgreSQL 和 Oracle 方言的 Interval 数据类型实现了 “字面值处理”,允许字面渲染 interval 值。感谢 Indivar Mishra 提供的 pull 请求。

    参考链接: #9737

  • [sql] [bug]

    修复了在某些组合中使用 literal_execute=True 多次使用相同绑定参数与其他字面渲染参数时,由于迭代问题导致渲染错误值的问题。

    此更改也已向后移植到:1.4.50

    参考链接: #10142

  • [sql] [bug]

    为所有包含字面值处理的数据类型的 “字面值处理器” 添加了编译器级别的 None/NULL 处理,即,对于所有不包含显式 “null 值” 处理的类型,值以内联方式渲染在 SQL 语句中,而不是作为绑定参数。以前,此行为是未定义且不一致的。

    参考链接: #10535

  • [sql]

    删除了未使用的占位符方法 TypeEngine.compare_against_backend()。此方法由非常旧版本的 Alembic 使用。有关详细信息,请参阅 https://github.com/sqlalchemy/alembic/issues/1293

asyncio

postgresql

  • [postgresql] [bug]

    修复了由 #7744 引起的 2.0 回归问题,其中涉及 PostgreSQL JSON 运算符与其他运算符(如字符串连接)组合的表达式链会丢失正确的括号,这是由于 PostgreSQL 方言特有的实现细节造成的。

    参考链接: #10479

  • [postgresql] [bug]

    修复了在使用 asyncpg 后端时,BIT 数据类型的 “insertmanyvalues” 的 SQL 处理。asyncpg 上的 BIT 显然需要使用 asyncpg 特定的 BitString 类型,该类型在使用此 DBAPI 时当前会暴露出来,使其与所有在此处使用普通位串的其他 PostgreSQL DBAPI 不兼容。版本 2.1 中的未来修复将规范化所有 PG 后端上的此数据类型。感谢 Sören Oldag 提供的 pull 请求。

    参考链接: #10532

mysql

  • [mysql] [bug]

    修复了 MySQL “预连接” 例程中的一个新不兼容性,其中传递给 connection.ping()False 参数(旨在禁用不需要的 “自动重新连接” 功能)在 MySQL 驱动程序和后端中已被弃用,并且对于某些版本的 MySQL 本机客户端驱动程序会产生警告。对于 mysqlclient,它已被删除,而对于 PyMySQL 和基于 PyMySQL 的驱动程序,该参数将在某个时候被弃用和删除,因此使用 API 自省来面向未来地防止这些不同阶段的删除。

    此更改也已向后移植到:1.4.50

    参考链接: #10492

mariadb

  • [mariadb] [bug]

    调整了 MySQL / MariaDB 方言,以便在使用 MariaDB 时,如果 Column.nullable 未指定显式的 TrueFalse 值,则将生成的列默认为 NULL,因为 MariaDB 不支持带有生成列的 “NOT NULL” 短语。感谢 Indivar 提供的 pull 请求。

    参考链接: #10056

  • [mariadb] [bug] [regression]

    针对 MySQL/MariaDB 驱动程序中似乎存在的固有问题建立了一个解决方法,其中对于 DELETE DML 的 RETURNING 结果(使用 SQLAlchemy 的 “empty IN” 条件返回零行)未能提供 cursor.description,从而产生返回零行的结果,导致 ORM 的回归,ORM 在 2.0 系列中使用 RETURNING 进行批量 DELETE 语句以实现 “synchronize session” 功能。为了解决这个问题,当检测到 “在给出 RETURNING 时没有描述” 的特定情况时,将生成一个带有正确游标描述的 “空结果”,并用作无法正常工作的游标的替代。

    参考文献: #10505

mssql

  • [mssql] [用例]

    为 SQL Server 增加了对 aioodbc 驱动的支持,该驱动构建于 pyodbc 和通用的 aio* 方言架构之上。

    另请参阅

    aioodbc - 位于 SQL Server 方言文档中。

    参考文献: #6521

  • [mssql] [错误] [反射]

    修复了对于具有较大自增起始值(超过 18 位数字)的 bigint 列,标识列反射会失败的问题。

    此更改也已向后移植到:1.4.50

    参考文献: #10504

oracle

  • [oracle] [错误]

    修复了 Interval 数据类型中的问题,其中 Oracle 实现未被用于 DDL 生成,导致 day_precisionsecond_precision 参数被忽略,尽管此方言支持这些参数。感谢 Indivar 提供 Pull request。

    参考文献: #10509

  • [oracle] [错误]

    修复了 cx_Oracle 方言声称支持比 SQLAlchemy 2.0 系列实际支持的更低的 cx_Oracle 版本 (7.x) 的问题。该方言导入了仅在 cx_Oracle 8 或更高版本中才有的符号,因此运行时方言检查以及 setup.cfg 要求已更新以反映此兼容性。

    参考文献: #10470

2.0.22

发布日期: 2023 年 10 月 12 日

orm

  • [orm] [用例]

    添加了方法 Session.get_one(),其行为类似于 Session.get(),但如果没有找到具有所提供主键的实例,则会引发异常而不是返回 None。感谢 Carlos Sousa 提供 Pull request。

    参考文献: #10202

  • [orm] [用例]

    添加了一个永久关闭会话的选项。将新参数 Session.close_resets_only 设置为 False 将阻止 Session 在调用 Session.close() 后执行任何其他操作。

    添加了新方法 Session.reset(),它会将 Session 重置为其初始状态。这是 Session.close() 的别名,除非 Session.close_resets_only 设置为 False

    参考文献: #7787

  • [orm] [错误]

    修复了当在 pep-593 Annotated 对象内部使用 mapped_column() 对象时,大量 mapped_column() 参数未被传递的问题,包括 mapped_column.sort_order, mapped_column.deferred, mapped_column.autoincrement, mapped_column.system, mapped_column.info 等。

    此外,在 Annotated 接收的 mapped_column() 中指示的 dataclass 参数,例如 mapped_column.kw_only, mapped_column.default_factory 等,仍然不受支持,因为 pep-681 Dataclass Transforms 不支持此功能。当在 Annotated 中以这种方式使用这些参数时,现在会发出警告(并且它们将继续被忽略)。

    参考文献: #10046, #10369

  • [orm] [错误]

    修复了当使用 ORM 中新的 select() 查询调用 Result.unique() 时,如果一个或多个列产生“未知哈希性”的值,通常在使用 JSON 函数(如 func.json_build_object())而未提供类型时,当返回的值实际上不可哈希时,会在内部失败的问题。行为已修复为在这种情况下测试接收到的对象的哈希性,如果不可哈希则引发信息性错误消息。请注意,对于“已知不可哈希”的值,例如当直接使用 JSONARRAY 类型时,已经会引发信息性错误消息。

    此处的“哈希性测试”修复也应用于旧版 Query,但在旧版情况下,几乎所有查询都使用 Result.unique(),因此此处不会发出新的警告;在这种情况下,回退到使用 id() 的旧版行为得以保留,改进之处在于,现在将对未知类型进行唯一化处理,如果该类型被证明是可哈希的,而以前则不会。

    参考文献: #10459

  • [orm] [错误]

    修复了最近修订的 “insertmanyvalues” 功能(可能是问题 #9618)中的回归问题,其中在 implicit_returning=False 参数应用于映射的 Table 的情况下,ORM 会错误地尝试将非 RETURNING 结果解释为具有 RETURNING 的结果,表明如果未提供主键值,则无法使用 “insertmanyvalues”。

    参考文献: #10453

  • [orm] [错误]

    修复了 ORM with_loader_criteria() 不会将其自身应用于 Select.join() 的错误,其中 ON 子句作为纯 SQL 比较给出,而不是作为关系目标或类似物。

    更新 - 发现这也修复了单继承标准无法正确应用于仅出现在 select_from() 列表中的子类实体的问题,请参阅 #11412

    参考文献: #10365, #11412

  • [orm] [错误]

    修复了在给定的注解中,当 Mapped 符号(如 WriteOnlyMappedDynamicMapped)作为子模块的元素被引用时,无法正确解析的问题,假设使用基于字符串或 “future annotations” 风格的注解。

    参考文献: #10412

  • [orm] [错误]

    修复了 __allow_unmapped__ 声明性选项的问题,其中使用集合类型(例如 list[SomeClass] 与 typing 构造 List[SomeClass])声明的类型无法被正确识别。感谢 Pascal Corpet 提供 Pull request。

    参考文献: #10385

engine

  • [engine] [错误]

    修复了某些方言中,由于预取或后取行的主键仍然存在,方言可能会为实际上根本不返回行的 INSERT 语句错误地返回空结果集的问题。受影响的方言包括 asyncpg 和所有 mssql 方言。

  • [engine] [错误]

    修复了在某些垃圾回收/异常情况下,连接池的清理例程会由于意外的状态集而引发错误的问题,这种情况可以在特定条件下重现。

    参考文献: #10414

sql

  • [sql] [错误]

    修复了在 UPDATE 语句的 SET 子句中引用 FROM 条目时,如果该条目在语句的其他任何地方都不存在,则不会将其包含在 UPDATE 语句的 FROM 子句中的问题;这种情况目前发生在通过 Update.add_cte() 添加的 CTE 中,以便在语句顶部提供所需的 CTE。

    参考文献: #10408

  • [sql] [错误]

    修复了 2.0 版本中的回归问题,其中 DDL 构造不再 __repr__(),原因是删除了 on 属性而未进行调整。感谢 Iuri de Silvio 提供 Pull request。

    参考文献: #10443

typing

  • [typing] [错误]

    修复了 typing 问题,其中传递给 Values 的参数列表过于严格地绑定到 List 而不是 Sequence。感谢 Iuri de Silvio 提供 Pull request。

    参考文献: #10451

  • [typing] [错误]

    更新代码库以支持 Mypy 1.6.0。

asyncio

mariadb

  • [mariadb] [错误]

    修改了 mariadb-connector 驱动程序,为所有查询预加载 cursor.rowcount 值,以适应 Pandas 等工具,这些工具硬编码为此方式调用 Result.rowcount。SQLAlchemy 通常仅为 UPDATE/DELETE 语句预加载 cursor.rowcount,否则会传递到 DBAPI,如果值不可用,DBAPI 可能会返回 -1。但是,mariadb-connector 不支持在游标本身关闭后调用 cursor.rowcount,而是引发错误。已添加通用测试支持,以确保所有后端都支持在结果关闭后允许 Result.rowcount 成功(即,返回整数值,-1 表示 “不可用”)。

    参考文献: #10396

  • [mariadb] [错误]

    对 mariadb-connector 方言进行了其他修复,以支持 INSERT..RETURNING 语句中结果中的 UUID 数据值。

mssql

  • [mssql] [错误]

    修复了在 SQL Server 上阻止 ORDER BY 在子查询中发出的规则在 select.fetch() 方法与 WITH TIES 或 PERCENT 结合使用以限制行数的情况下未被禁用的错误,从而阻止了使用 TOP / ORDER BY 的有效子查询。

    参考文献: #10458

2.0.21

发布日期: 2023 年 9 月 18 日

orm

  • [orm] [错误]

    调整了 ORM 对 UpdateDelete 中使用的 “target” 实体的解释,以不干扰传递给语句的目标 “from” 对象,例如当传递应在 “UPDATE FROM” 之类的短语中维护的 ORM 映射的 aliased 构造时。诸如使用 “SELECT” 语句的 ORM 会话同步(例如 MySQL/MariaDB)之类的案例在使用这种类型的 DML 语句时仍然存在问题,因此最好在使用此类 DML 语句时禁用 synchonize_session。

    参考文献: #10279

  • [orm] [错误]

    selectin_polymorphic() 加载器选项添加了新功能,该功能允许将其他加载器选项捆绑为兄弟项,并在父加载器选项的子选项中引用其子类之一。以前,仅当 selectin_polymorphic() 位于查询选项的顶层时,才支持此模式。有关示例,请参阅新的文档部分。

    作为此更改的一部分,改进了 Load.selectin_polymorphic() 方法/加载器策略的行为,以便当对已在关系加载的类使用该选项时,子类加载不会从父表中加载大多数已加载的列。以前,仅加载子类列的逻辑仅适用于顶层类加载。

    参考文献: #10348

engine

  • [engine] [错误]

    修复了一系列反射问题,这些问题影响了 PostgreSQL、MySQL/MariaDB 和 SQLite 方言,当反射外键约束时,目标列的表名或列名中包含括号。

    参考文献: #10275

sql

  • [sql] [用例]

    调整了 Enum 数据类型,使其接受 None 作为 Enum.length 参数的参数,从而在生成的 DDL 中产生没有长度的 VARCHAR 或其他文本类型。这允许在类型存在于模式中之后向该类型添加任何长度的新元素。感谢 Eugene Toder 提供 Pull request。

    参考文献: #10269

  • [sql] [用例]

    添加了新的通用 SQL 函数 aggregate_strings,它接受 SQL 表达式和分隔符,将多行字符串连接成单个聚合值。该函数在每个后端编译为诸如 group_concat()string_agg()LISTAGG() 之类的函数。感谢 Joshua Morris 提供 Pull request。

    参考文献: #9873

  • [sql] [错误]

    调整了字符串连接运算符的运算符优先级,使其与字符串匹配运算符(如 ColumnElement.like()ColumnElement.regexp_match()ColumnElement.match() 等)以及与字符串比较运算符具有相同优先级的普通 == 的优先级相同,以便将括号应用于跟随字符串匹配运算符的字符串连接表达式。这为 PostgreSQL 等后端提供了支持,其中 “regexp match” 运算符的优先级显然高于字符串连接运算符。

    参考文献: #9610

  • [sql] [错误]

    限定了 DDL 编译器中 hashlib.md5() 的使用,该函数用于为 DDL 语句中的长索引和约束名称生成确定性的四字符后缀,以包含 Python 3.9+ usedforsecurity=False 参数,以便为受限环境(如 FIPS)构建的 Python 解释器不会认为此调用与安全问题相关。

    参考文献: #10342

  • [sql] [错误]

    Values 构造现在将自动创建 column 的代理(即副本),如果该列已与现有 FROM 子句关联。这允许 values_obj.c.colname 之类的表达式即使在 colname 作为已与先前的 Values 或其他表构造一起使用的 column 传递的情况下,也能生成正确的 FROM 子句。最初,这被认为是错误条件的候选对象,但很可能这种模式已经得到广泛使用,因此现在已添加到支持中。

    参考文献: #10280

schema

  • [schema] [错误]

    修改了 Oracle 独有的 Identity.order 参数的呈现方式,该参数是 SequenceIdentity 的一部分,使其仅在 Oracle 后端发生,而不在 PostgreSQL 等其他后端发生。未来的版本将重命名 Identity.orderSequence.orderIdentity.on_null 参数为 Oracle 特定的名称,并弃用旧名称,因为这些参数仅适用于 Oracle。

    此更改也已向后移植到:1.4.50

    参考文献: #10207

typing

  • [typing] [用例]

    使 Mapped 的包含类型协变;这是为了为最终用户类型场景提供更大的灵活性,例如使用协议来表示传递给其他函数的特定映射类结构。作为此更改的一部分,包含类型也为依赖和相关类型(如 SQLORMOperationsWriteOnlyMappedSQLColumnExpression)设为协变。感谢 Roméo Després 提供 Pull request。

    参考文献: #10288

  • [typing] [错误]

    修复了 2.0.20 中通过 #9600 修复引入的回归问题,该修复尝试为 MetaData.naming_convention 添加更正式的 typing。此更改阻止了基本命名约定字典通过 typing,并且已进行调整,以便再次接受键为字符串的普通字典以及使用约束类型作为键或两者混合的字典。

    作为此更改的一部分,命名约定字典的较少使用的形式也被 typing 化,包括它当前允许 Constraint 类型对象作为键。

    参考文献: #10264, #9284

  • [typing] [错误]

    修复了应用于表达式构造基类 Visitable 类的 __class_getitem__() 的类型注释,以接受 Any 作为键,而不是 str。这有助于某些 IDE,例如 PyCharm,在尝试为包含泛型选择器的 SQL 构造编写类型注释时。感谢 Jordan Macdonald 提交的 Pull Request。

    参考链接: #9878

  • [typing] [bug]

    修复了核心 “SQL 元素” 类 SQLCoreOperations,使其从类型角度支持 __hash__() 方法。因为诸如 Column 和 ORM InstrumentedAttribute 等对象是可哈希的,并且在 UpdateInsert 构造的公共 API 中用作字典键。此前,类型检查器无法识别根 SQL 元素是可哈希的。

    参考链接: #10353

  • [typing] [bug]

    修复了 Existing.select_from() 的类型问题,该问题阻止了其与 ORM 类一起使用。

    参考链接: #10337

  • [typing] [bug]

    更新了 ORM 加载选项的类型注释,限制它们仅接受 “*” 而不是任何字符串作为字符串参数。感谢 Janek Nouvertné 提交的 Pull Request。

    参考链接: #10131

postgresql

  • [postgresql] [bug]

    修复了 2.0 版本中由于 #8491 引入的回归问题。当 create_engine.pool_pre_ping 参数在使用时,用于 PostgreSQL 方言的修订版 “ping” 会干扰 asyncpg 与 PGBouncer “transaction” 模式的使用。因为 asnycpg 发出的多个 PostgreSQL 命令可能会在多个连接之间拆分,从而由于新修订的 “ping” 周围缺少事务而导致错误。现在 ping 在事务中被调用,这与所有其他基于 pep-249 DBAPI 的后端隐式的方式相同;这保证了 asyncpg 为此命令发送的一系列 PG 命令在同一个后端连接上被调用,而不会在命令执行过程中跳转到不同的连接。如果 asyncpg 方言在 “AUTOCOMMIT” 模式下使用,则不使用事务,这仍然与 pgbouncer transaction 模式不兼容。

    参考链接: #10226

misc

  • [bug] [setup]

    修复了一个非常老旧的问题,即 SQLAlchemy 模块的完整范围,包括 sqlalchemy.testing.fixtures,无法在 pytest 运行之外导入。这适用于诸如 pkgutil 等尝试导入所有包中所有已安装模块的检查实用程序。

    参考链接: #10321

2.0.20

发布日期: 2023 年 8 月 15 日

orm

  • [orm] [usecase]

    为启用 ORM 的 DML 语句实现了 “RETURNING ‘*’” 用例。这将尽可能多地呈现并返回未过滤的结果集,但不适用于具有特定列呈现要求的、多参数的 “ORM 批量 INSERT” 语句。

    参考链接: #10192

  • [orm] [bug]

    修复了一个根本问题,该问题阻止了某些形式的 ORM “注解” 在子查询中生效,这些子查询使用了 Select.join() 对关系目标进行连接。当子查询在特殊情况下使用时,例如在 PropComparator.and_() 和其他 ORM 特定的场景中,会使用这些注解。

    此更改也已向后移植到:1.4.50

    参考链接: #10223

  • [orm] [bug]

    修复了当超类和子类中存在同名列的连接继承模型时,ORM 从该模型生成 SELECT 语句,有时不会将正确的列名列表发送到 CTE 构造的问题,尤其是在生成 RECURSIVE 列列表时。

    参考链接: #10169

  • [orm] [bug]

    修复了一个相当严重的问题,即传递给 Session.execute() 的执行选项,以及 ORM 执行语句本地的执行选项,不会传播到预先加载器,例如 selectinload(), immediateload(), 和 sqlalchemy.orm.subqueryload()。这导致无法执行诸如为单个语句禁用缓存或为单个语句使用 schema_translate_map 以及使用用户自定义执行选项等操作。已进行更改,使得 Session.execute()所有面向用户的执行选项都将传播到额外的加载器。

    作为此更改的一部分,可以通过将 execution_options={"compiled_cache": None} 发送到 Session.execute() 来针对每个语句静默 “过度深入” 的预先加载器导致的缓存禁用警告,这将禁用该范围内所有语句的缓存。

    参考链接: #10231

  • [orm] [bug]

    修复了 ORM 用于诸如 Comparator.any() 等表达式的内部克隆,以生成关联的 EXISTS 构造,会干扰 SQL 编译器的 “笛卡尔积警告” 功能的问题,导致 SQL 编译器在语句的所有元素都正确连接时发出警告。

    参考链接: #10124

  • [orm] [bug]

    修复了 lazy="immediateload" 加载策略会在不应发生加载的情况下(例如在递归自引用加载中)将内部加载令牌放入 ORM 映射属性中的问题。作为此更改的一部分,lazy="immediateload" 策略现在像其他预先加载器一样,遵守自引用预先加载的 relationship.join_depth 参数,其中将其保持未设置或设置为零将导致不发生自引用立即加载,将其设置为大于或等于 1 的值将立即加载到给定的深度。

    参考链接: #10139

  • [orm] [bug]

    修复了基于字典的集合(例如 attribute_keyed_dict())无法完全正确地 pickle/unpickle 的问题,这导致在 unpickle 后尝试修改此类集合时出现问题。

    参考链接: #10175

  • [orm] [bug]

    修复了从另一个预先加载器链接 load_only() 或其他通配符使用 defer(),并对连接继承子类使用 aliased() 时,对超类本地的列不起作用的问题。

    参考链接: #10125

  • [orm] [bug]

    修复了启用 ORM 的 select() 构造不会呈现仅通过 Select.add_cte() 方法添加的 CTE,且该 CTE 在语句中没有其他引用的问题。

    参考链接: #10167

examples

  • [examples] [bug]

    dogpile_caching 示例已更新为 2.0 风格的查询。在 “缓存查询” 逻辑本身中,添加了一个条件来区分执行失效操作时的 Queryselect()

engine

sql

  • [sql] [bug]

    修复了 unpickle Column 或其他 ColumnElement 时无法恢复正确 “comparator” 对象的问题,该对象用于生成特定于类型对象的 SQL 表达式。

    此更改也已向后移植到:1.4.50

    参考链接: #10213

typing

asyncio

mysql

  • [mysql] [usecase]

    更新了 aiomysql 方言,因为该方言似乎再次得到维护。使用 0.2.0 版本重新添加到 ci 测试中。

    此更改也已向后移植到:1.4.50

2.0.19

发布日期: 2023 年 7 月 15 日

orm

  • [orm] [bug]

    修复了直接设置关系集合时,如果新集合中的对象已存在,则不会触发该对象的级联事件的问题,导致该对象如果尚未存在,则不会添加到 Session。这在性质上类似于 #6471,并且由于 2.0 系列中移除了 cascade_backrefs,因此问题更加明显。AttributeEvents.append_wo_mutation() 事件(作为 #6471 的一部分添加)现在也为集合的现有成员发出,这些成员存在于同一集合的批量设置中。

    参考链接: #10089

  • [orm] [bug]

    修复了通过反向引用与未加载的集合关联,但由于 2.0 系列中移除了 cascade_backrefs 而未合并到 Session 中的对象,即使它们是集合的待处理成员,也不会发出警告,提示这些对象未包含在 flush 中;在其他此类情况下,当 flush 的集合包含基本上会被丢弃的未附加对象时,会发出警告。为反向引用待处理集合成员添加警告,与可能存在或不存在,并可能根据不同的关系加载策略在不同时间 flush 或不 flush 的集合建立了更大的一致性。

    参考链接: #10090

  • [orm] [bug] [regression]

    修复了由 #9805 引起的额外回归问题,其中语句上 “ORM” 标志的更积极传播可能导致在核心 SQL 语句中嵌入 ORM Query 构造(尽管如此,该构造不包含 ORM 实体)时,发生内部属性错误,在本例中为启用 ORM 的 UPDATE 和 DELETE 语句。

    参考链接: #10098

engine

  • [engine] [bug]

    Row.tRow.tuple() 重命名为 Row._tRow._tuple();这是为了符合 Row 上的所有方法和预定义属性应采用 Python 标准库 namedtuple 的风格,其中所有固定名称都带有前导下划线的策略,以避免与现有列名冲突。先前的方法/属性现已弃用,并将发出弃用警告。

    参考链接: #10093

  • [engine] [bug]

    make_url() 函数中添加了对非字符串、非 URL 对象的检测,允许立即抛出 ArgumentError,而不是稍后导致故障。特殊逻辑确保允许通过 URL 的模拟形式。感谢 Grigoriev Semyon 提交的 Pull Request。

    参考链接: #10079

postgresql

  • [postgresql] [bug]

    修复了 #10004 中 PostgreSQL URL 解析改进引起的回归问题,其中包含冒号的 “host” 查询字符串参数(以支持各种第三方代理服务器和/或方言)无法正确解析,因为它们被评估为 host:port 组合。解析已更新为仅当主机名仅包含字母数字字符以及点或破折号(例如,没有斜杠),后跟一个冒号,然后是一个零个或多个整数的全整数标记时,才将冒号视为指示 host:port 值。在所有其他情况下,整个字符串都被视为主机。

    参考链接: #10069

  • [postgresql] [bug]

    修复了与 CITEXT 数据类型的比较会将右侧强制转换为 VARCHAR 的问题,导致右侧不会被解释为 CITEXT 数据类型,对于 asyncpg、psycopg3 和 pg80000 方言。这导致 CITEXT 类型基本上无法实际使用;现在已修复此问题,并且已更正测试套件以正确断言表达式呈现正确。

    参考链接: #10096

2.0.18

发布日期: 2023 年 7 月 5 日

engine

  • [engine] [bug]

    调整了 create_engine.schema_translate_map 功能,使得语句中的所有模式名称现在都被标记化,无论特定名称是否在给定的立即模式转换映射中,并且当键在执行时的实际模式转换映射中不存在时,都回退到替换原始名称。这两个更改允许重复使用已编译的对象,其模式 schema_translate_maps 在每次运行时都包含或不包含各种键,从而允许缓存的 SQL 构造在每次使用具有不同键集的模式转换映射时继续在运行时起作用。此外,还添加了对 schema_translate_map 字典的检测,这些字典在同一语句的调用之间获得或丢失 None 键,这会影响语句的编译并且与缓存不兼容;对于这些情况,会引发异常。

    参考链接: #10025

sql

  • [sql] [bug]

    修复了当使用 “flags” 时,ColumnOperators.regexp_match() 会产生 “不稳定” 缓存键的问题,即缓存键会持续更改,每次都会导致缓存污染。 ColumnOperators.regexp_replace() 在使用 flags 和实际替换表达式时也存在同样的问题。 Flags 现在表示为固定的修饰符字符串,以 safestrings 而非绑定参数的形式呈现,并且替换表达式在 “binary” 元素的主要部分中建立,以便它生成适当的缓存键。

    请注意,作为此更改的一部分,ColumnOperators.regexp_match.flagsColumnOperators.regexp_replace.flags 已被修改为仅呈现为文字字符串,而以前它们被呈现为完整的 SQL 表达式,通常是绑定参数。 这些参数应始终作为纯 Python 字符串传递,而不是作为 SQL 表达式构造传递; 预计在实践中不会为此参数使用 SQL 表达式构造,因此这是一个向后不兼容的更改。

    此更改还修改了生成的表达式的内部结构,对于有或没有 flags 的 ColumnOperators.regexp_replace() 以及带有 flags 的 ColumnOperators.regexp_match()。 可能已经实现了他们自己的 regexp 实现的第三方方言(搜索中找不到此类方言,因此预计影响很小)将需要调整结构的遍历以适应。

    此更改也 向后移植 到:1.4.49

    参考: #10042

  • [sql] [bug]

    修复了主要在内部使用的 CacheKey 构造中的问题,其中 __ne__() 运算符未正确实现,导致在相互比较 CacheKey 实例时产生无意义的结果。

    此更改也 向后移植 到:1.4.49

extensions

typing

  • [typing] [usecase]

    改进了使用来自 sqlalchemy.sql.operators 的独立运算符函数(例如 sqlalchemy.sql.operators.eq)时的类型标注。

    参考: #10054

  • [typing] [bug]

    修复了 aliased() 构造中的一些类型标注问题,以正确接受使用 Table.alias() 别名化的 Table 对象,以及对作为 “selectable” 参数传递的 FromClause 对象的通用支持,因为这些都是支持的。

    参考: #10061

postgresql

  • [postgresql] [usecase]

    为 asyncpg 方言添加了多主机支持。 还为 “multihost” 用例添加了 PostgreSQL URL 例程的通用改进和错误检查。 拉取请求由 Ilia Dmitriev 提供。

    另请参阅

    多主机连接

    参考: #10004

  • [postgresql] [bug]

    为所有 PostgreSQL 方言添加了新参数 native_inet_types=False,指示 DBAPI 使用的转换器将来自 PostgreSQL INETCIDR 列的行转换为 Python ipaddress 数据类型应被禁用,而是返回字符串。 这允许为这些数据类型编写以使用字符串的代码迁移到 asyncpg、psycopg 或 pg8000,而无需更改代码,只需将此参数添加到 create_engine()create_async_engine() 函数调用中。

    另请参阅

    网络数据类型

    参考: #9945

mariadb

  • [mariadb] [usecase] [reflection]

    允许从 MariaDB 反射 UUID 列。 这允许 Alembic 正确检测现有 MariaDB 数据库中此类列的类型。

    参考: #10028

mssql

  • [mssql] [usecase]

    在 MSSQL 方言中添加了对 COLUMNSTORE 索引的创建和反射的支持。 可以在指定 mssql_columnstore=True 的索引上指定。

    参考: #7340

  • [mssql] [bug] [sql]

    修复了将 Cast 转换为具有显式排序规则的字符串类型会在 CAST 函数内部呈现 COLLATE 子句的问题,这会导致语法错误。

    参考: #9932

2.0.17

发布日期:2023 年 6 月 23 日

orm

  • [orm] [bug] [regression]

    修复了 2.0 系列中的回归问题,即使用 undefer_group()selectinload()subqueryload() 的查询会引发 AttributeError。 拉取请求由 Matthew Martin 提供。

    参考: #9870

  • [orm] [bug]

    修复了 ORM 注解声明式中的问题,该问题阻止了在不返回 Mapped 数据类型,而是返回补充 ORM 数据类型(例如 AssociationProxy)的混入类上使用 declared_attr。 声明式运行时会错误地尝试将此注解解释为需要 Mapped 并引发错误。

    参考: #9957

  • [orm] [bug] [typing]

    修复了类型标注问题,其中不允许从 declared_attr 函数返回 AssociationProxy 返回类型。

    参考: #9957

  • [orm] [bug] [regression]

    修复了 #9879 在 2.0.16 中引入的回归问题,其中将可调用对象传递给 mapped_column.default 参数,同时设置 init=False 会将此值解释为 Dataclass 默认值,该值将直接分配给对象的新实例,从而绕过作为底层 Column 上的 Column.default 值生成器发生的默认生成器。 现在检测到此条件,以便保持以前的行为,但是为此模棱两可的用法发出了弃用警告; 要填充 Column 的默认生成器,应使用 mapped_column.insert_default 参数,这与 mapped_column.default 参数区分开来,后者的名称根据 pep-681 是固定的。

    参考: #9936

  • [orm] [bug]

    为 ORM Session “状态更改” 系统添加了额外的强化和文档,该系统检测 SessionAsyncSession 对象的并发使用; 在从底层引擎获取连接的过程中添加了额外的检查,这对于内部连接管理至关重要。

    参考: #9973

  • [orm] [bug]

    修复了 ORM 加载器策略逻辑中的问题,该问题进一步允许复杂的继承多态 / 别名 / of_type() 关系链中的长链 contains_eager() 加载器选项在查询中生效。

    参考: #10006

  • [orm] [bug]

    修复了对 registry.type_annotation_mapEnum 数据类型的支持问题,该支持最初作为 #8859 的一部分添加,其中在映射中使用带有固定配置的自定义 Enum 将无法传输 Enum.name 参数,这在其他问题中会阻止 PostgreSQL 枚举在枚举值作为单独值传递时工作。 逻辑已更新,以便 “name” 被传输,而且针对纯 Python enum.Enum 类或其他 “空” 枚举的默认 Enum 也不会设置硬编码名称 "enum"

    参考: #9963

orm declarative

  • [orm] [declarative] [bug]

    当 ORM relationship() 和其他 MapperProperty 对象一次分配给两个不同的类属性时,会发出警告; 只有一个属性将被映射。 对于 Columnmapped_column 对象,此条件的警告已经存在。

    参考: #3532

extensions

  • [extensions] [bug]

    修复了 mypy 插件与 mypy 1.4 一起使用的问题。

    此更改也 向后移植 到:1.4.49

typing

postgresql

  • [postgresql] [usecase]

    pg8000 方言现在支持 RANGE 和 MULTIRANGE 数据类型,使用 Range 和 Multirange 类型 中描述的现有 RANGE API。 pg8000 驱动程序从 1.29.8 版本开始支持 Range 和 multirange 类型。 拉取请求由 Tony Locke 提供。

    参考: #9965

2.0.16

发布日期:2023 年 6 月 10 日

platform

  • [platform] [usecase]

    允许完整测试套件在 Python 3.12.0b1 上通过的兼容性改进。

orm

  • [orm] [usecase]

    改进了 DeferredReflection.prepare() 以接受传递给 MetaData.reflect() 的任意 **kw 参数,从而允许诸如反射视图以及传递方言特定参数的用例。 此外,现代化了 DeferredReflection.prepare.bind 参数,以便 EngineConnection 都可以作为 “bind” 参数接受。

    参考: #9828

  • [orm] [bug]

    修复了 DeclarativeBaseNoMeta 声明式基类无法与非映射混入类或抽象类一起使用的问题,而是引发 AttributeError

    参考: #9862

  • [orm] [bug] [regression]

    修复了 2.0 系列中的回归问题,其中 validates.include_backrefs 的默认值对于 validates() 函数已更改为 False。 此默认值现在已恢复为 True

    参考: #9820

  • [orm] [bug]

    修复了新功能中的错误,该功能允许 WHERE 子句与 ORM 批量主键更新 结合使用,该功能在 2.0.11 版本中作为 #9583 的一部分添加,其中发送不包含每行主键值的字典将通过批量处理并为行包含 “pk=NULL”,从而静默失败。 如果未提供批量 UPDATE 的主键值,则现在会引发异常。

    参考: #9917

  • [orm] [bug] [dataclasses]

    修复了生成指定 default 值并设置 init=False 的 dataclasses 字段不起作用的问题。 在这种情况下,dataclasses 的行为是在类上设置默认值,这与 SQLAlchemy 使用的描述符不兼容。 为了支持这种情况,默认值在生成 dataclass 时转换为 default_factory

    参考: #9879

  • [orm] [bug]

    每当将属性添加到 Mapper 时,都会发出弃用警告,其中已配置 ORM 映射属性,或者类上已存在属性。 以前,对于这种情况存在非弃用警告,但并未一致地发出。 此警告的逻辑已得到改进,以便它可以检测最终用户替换属性,同时不会对内部声明式和其他预期替换描述符的情况产生误报。

    参考: #9841

  • [orm] [bug]

    改进了 registry.map_imperatively() 方法的 map_imperatively.local_table 参数的参数检查,确保仅传递 Table 或其他 FromClause,而不是现有的映射类,这会导致未定义的行为,因为该对象会被进一步解释为新映射。

    参考: #9869

  • [orm] [bug]

    InstanceState.unloaded_expirable 属性是 InstanceState.unloaded 的同义词,现在已弃用; 此属性始终是特定于实现的,不应公开。

    参考: #9913

asyncio

postgresql

  • [postgresql] [usecase] [reflection]

    在使用 PostgreSQL 反射中的 ARRAY_AGG 时,将 NAME 列转换为 TEXT。 这似乎提高了与某些可能不支持 NAME 类型聚合的 PostgreSQL 衍生版本的兼容性。

    参考: #9838

  • [postgresql] [usecase]

    统一了自定义 PostgreSQL 运算符定义,因为它们在多个不同的数据类型之间共享。

    参考: #9041

  • [postgresql] [usecase]

    使用方言选项 postgresql_nulls_not_distinct 添加了对 PostgreSQL 10 NULLS NOT DISTINCT 功能的支持,用于唯一索引和唯一约束。 更新了反射逻辑,以正确考虑此选项。 拉取请求由 Pavel Siarchenia 提供。

    参考: #8240

  • [postgresql] [bug]

    在 PostgreSQL 特定运算符(例如 @>)上使用适当的优先级。 以前,优先级是错误的,导致在针对 ANYALL 构造进行渲染时出现错误的括号。

    参考: #9836

  • [postgresql] [bug]

    修复了 ColumnOperators.like.escape 和类似的参数不允许将空字符串作为将作为 “escape” 字符传递的参数的问题; 这是 PostgreSQL 支持的语法。 拉取请求由 Martin Caslavsky 提供。

    参考: #9907

2.0.15

发布日期:2023 年 5 月 19 日

orm

  • [orm] [bug]

    随着越来越多的项目使用新的 “2.0” ORM 查询,基于给定语句是否引用 ORM 实体而定的 “autoflush” 的条件性质变得越来越像关键行为。 到目前为止,语句的 “ORM” 标志一直松散地基于语句是否返回与 ORM 实体或列对应的行; “ORM” 标志的最初目的是启用 ORM 实体获取规则,这些规则将后处理应用于 Core 结果集以及应用于语句的 ORM 加载器策略。 对于不基于包含 ORM 实体的行构建的语句,“ORM” 标志被认为在很大程度上是不必要的。

    即使对于纯粹的 Core SQL 构造, “autoflush” 仍然可能更适合应用于 Session.execute() 和相关方法的所有用法。然而,这仍然可能会影响到不期望出现这种情况的旧有场景,并且可能更像是 2.1 版本的功能。但就目前而言,“ORM 标志”的规则已经放宽,因此,只要语句在任何位置包含 ORM 实体或属性,包括仅在 WHERE / ORDER BY / GROUP BY 子句中,标量子查询中等等,都将启用此标志。这将导致此类语句发生 “autoflush”,并且也可以通过 ORMExecuteState.is_orm_statement 事件级别的属性看到。

    参考链接: #9805

postgresql

  • [postgresql] [bug] [回归]

    修复了 PostgreSQL 方言的基本 Uuid 数据类型,以便在选择 “native_uuid” 时充分利用 PG 特定的 UUID 方言特定数据类型,从而包含 PG 驱动程序的行为。这个问题在 #9618 中作为 insertmanyvalues 改进的一部分变得明显,其方式与 #9739 类似,asyncpg 驱动程序对数据类型转换的存在与否非常敏感,并且当使用此通用类型时,必须调用 PostgreSQL 驱动程序特定的原生 UUID 数据类型,以便进行这些转换。

    参考链接: #9808

2.0.14

发布日期:2023 年 5 月 18 日

orm

  • [orm] [bug]

    修改了 JoinedLoader 的实现,在一个特定区域使用更简单的方法,该区域之前使用了一个将在线程之间共享的缓存结构。 这样做的理由是为了避免潜在的竞争条件,怀疑这是多次报告的特定崩溃的原因。 有问题的缓存结构仍然最终通过编译后的 SQL 缓存 “缓存”,因此预计不会出现性能下降。

    参考链接: #9777

  • [orm] [bug] [回归]

    修复了回归问题,即在 CTE 构造中使用 update()delete(),然后在 select() 中使用,会由于执行 ORM 级别更新/删除语句的 ORM 相关规则而引发 CompileError

    参考链接: #9767

  • [orm] [bug]

    修复了新的 ORM 注解式声明中的问题,即在 mapped_column() 中使用 ForeignKey (或其他列级约束),然后通过 pep-593 Annotated 复制到模型中,会将每个约束的重复项应用于目标 Table 中生成的 Column,从而导致不正确的 CREATE TABLE DDL 以及 Alembic 下的迁移指令。

    参考链接: #9766

  • [orm] [bug]

    修复了在使用带有 joinedload() 加载器选项的附加关系条件时,如果附加条件本身包含引用连接实体的相关子查询,因此也需要 “适应” 别名实体,则会被排除在此适应之外,从而为 joinedload 生成错误的 ON 子句的问题。

    参考链接: #9779

sql

  • [sql] [usecase]

    将 MSSQL try_cast() 函数推广到 sqlalchemy. 导入命名空间,以便第三方方言也可以实现它。 在 SQLAlchemy 中,try_cast() 函数仍然是仅限 SQL Server 的构造,如果与不支持它的后端一起使用,则会引发 CompileError

    try_cast() 实现了 CAST,其中无法转换的转换将作为 NULL 返回,而不是引发错误。 理论上,Google BigQuery、DuckDB 和 Snowflake 以及可能的其他方言可以实现此构造。

    拉取请求由 Nick Crews 友情提供。

    参考链接: #9752

  • [sql] [bug]

    修复了 values() 构造中的问题,如果在标量子查询内部使用该构造,则会发生内部编译错误。

    参考链接: #9772

postgresql

  • [postgresql] [bug]

    修复了一个显然非常古老的问题,即 ENUM.create_type 参数,当设置为非默认值 False 时,在复制作为其一部分的 Column 时不会传播,这在使用 ORM 声明式混入时很常见。

    参考链接: #9773

tests

  • [tests] [bug] [pypy]

    修复了依赖于 sys.getsizeof() 函数的测试,使其不在 pypy 上运行,因为此函数在 pypy 上的行为似乎与在 cpython 上的行为不同。

    参考链接: #9789

2.0.13

发布日期:2023 年 5 月 10 日

orm

  • [orm] [bug]

    修复了 ORM 注解式声明在所有情况下都无法正确解析前向引用的问题; 特别是,当结合 Pydantic 数据类使用 from __future__ import annotations 时。

    参考链接: #9717

  • [orm] [bug]

    修复了新特性 在 upsert 语句中使用 RETURNING 中的问题,其中 populate_existing 执行选项未传播到加载选项,从而阻止了现有属性被就地刷新。

    参考链接: #9746

  • [orm] [bug]

    修复了加载器策略路径问题,其中诸如 joinedload() / selectinload() 之类的预先加载器在多层深度遍历时,在中间成员具有 with_polymorphic() 或类似构造的加载后,将无法完全遍历。

    参考链接: #9715

  • [orm] [bug]

    修复了 mapped_column() 构造中的问题,当 ORM 映射属性引用相同的 Column 时,如果涉及 mapped_column() 构造,则不会发出关于 “列 X 被直接命名多次” 的正确警告,而是引发内部断言。

    参考链接: #9630

sql

  • [sql] [usecase]

    为 UPDATE 和 DELETE 语句实现了 “笛卡尔积警告”,这些语句包含多个未以某种方式关联在一起的表。

    参考链接: #9721

  • [sql] [bug]

    修复了方言特定 float/double 类型的基类; Oracle BINARY_DOUBLE 现在是 Double 的子类,并且用于 asyncpg 和 pg8000 的 Float 的内部类型现在正确地子类化了 Float

  • [sql] [bug]

    修复了包含多个表且没有 VALUES 子句的 update() 构造会引发内部错误的问题。 Update 在没有值的情况下的当前行为是生成带有空 “set” 子句的 SQL UPDATE 语句,因此对于此特定子情况,已使其保持一致。

schema

  • [schema] [performance]

    改进了表列的添加方式,避免了不必要的分配,显着加快了创建许多表的速度,例如在反射整个模式时。

    参考链接: #9597

typing

asyncio

  • [asyncio] [usecase]

    添加了一个新的辅助混入类 AsyncAttrs,旨在改进异步 asyncio 中延迟加载器和其它过期或延迟的 ORM 属性的使用,提供一个简单的属性访问器,为任何 ORM 属性提供 await 接口,无论它是否需要发出 SQL。

    另请参阅

    AsyncAttrs

    参考链接: #9731

  • [asyncio] [bug]

    修复了半私有的 await_only()await_fallback() 并发函数中的问题,如果函数抛出 GreenletError,则给定的 awaitable 对象将保持未等待状态,如果程序继续运行,则稍后可能会导致 “was not awaited” 警告。 在这种情况下,给定的 awaitable 对象现在在抛出异常之前被取消。

postgresql

  • [postgresql] [bug] [regression]

    修复了由于 2.0.10 中作为 #9618 一部分进行的 “insertmanyvalues” 更改而导致的另一个回归问题,与回归问题 #9701 类似,LargeBinary 数据类型在使用 asyncpg 驱动程序时也需要额外的转换,以便与新的批量 INSERT 格式一起使用。

    参考链接: #9739

oracle

  • [oracle] [reflection]

    在 Oracle 方言中添加了对基于表达式的索引和索引表达式的排序方向的反射支持。

    参考链接: #9597

misc

  • [bug] [ext]

    修复了 Mutable 中的问题,其中 ORM 映射属性的事件注册会为映射的继承子类重复调用,从而导致在继承层次结构中调用重复事件。

    参考链接: #9676

2.0.12

发布日期:2023 年 4 月 30 日

orm

  • [orm] [bug]

    修复了关键的缓存问题,其中 aliased()hybrid_property() 表达式组合会导致缓存键不匹配,从而导致缓存键保留实际的 aliased() 对象,同时也不匹配等效构造,从而填满缓存。

    此更改也向后移植到:1.4.48

    参考链接: #9728

mysql

  • [mysql] [bug] [mariadb]

    修复了关于 TableColumn 对象的注释反射的问题,其中注释包含控制字符(如换行符)。 还添加了对这些字符以及表和列注释中的扩展 Unicode 字符(后者 MySQL/MariaDB 不支持)的额外测试支持,以进行整体测试。

    参考链接: #9722

2.0.11

发布日期:2023 年 4 月 26 日

orm

  • [orm] [usecase]

    ORM 批量 INSERT 和 UPDATE 功能现在添加了以下功能

    • 取消了在使用 “orm” dml_strategy 设置的 ORM INSERT 时,不传递额外参数的要求。

    • 取消了在使用 “bulk” dml_strategy 设置的 ORM UPDATE 时,不传递额外 WHERE 条件的要求。 请注意,在这种情况下,将关闭对预期行数的检查。

    参考链接: #9583, #9595

  • [orm] [bug]

    修复了 2.0 回归问题,其中在 Insert.values() 内部使用 bindparam() 会在通过 ORM Session 执行 Insert 语句时无法正确解释,这是由于新的 启用 ORM 的插入功能 未实现此用例。

    参考链接: #9583, #9595

engine

  • [engine] [performance]

    Row 进行了一系列性能增强

    • 改进了行的 “命名元组” 接口的 __getattr__ 性能; 在此更改中,Row 实现已得到简化,删除了特定于 SQLAlchemy 1.4 及更早版本的构造和逻辑。 作为此更改的一部分,Row 的序列化格式已略作修改,但是,使用以前的 SQLAlchemy 2.0 版本 pickle 的行将在新格式中被识别。 拉取请求由 J. Nick Koston 友情提供。

    • 通过使 “bytes” 处理程序以每个驱动程序为基础进行条件化,提高了 “binary” 数据类型的行处理性能。 因此,除了 psycopg2 之外,几乎所有驱动程序都已删除了 “bytes” 结果处理程序,所有这些驱动程序的现代形式都支持直接返回 Python “bytes”。 拉取请求由 J. Nick Koston 友情提供。

    • Federico Caselli 对 Row 内部进行了额外的重构,以提高性能。

    参考链接: #9678, #9680

  • [engine] [bug] [regression]

    修复了阻止 URL.normalized_query 属性的回归问题,该属性阻止了 URL 的正常运行。

    参考链接: #9682

sql

  • [sql] [usecase]

    添加了对使用 ColumnCollection 进行切片访问的支持,例如 table.c[0:5], subquery.c[:-1] 等。 切片访问返回一个子 ColumnCollection,方式与传递键元组相同。 这是为 #8285 添加的键元组访问的自然延续,其中切片访问用例的遗漏似乎是一个疏忽。

    参考链接: #8285

typing

  • [typing] [bug]

    改进了 RowMapping 的类型提示,以指示它也支持 Column 作为索引对象,而不仅仅是字符串名称。 拉取请求由 Andy Freeland 友情提供。

    参考链接: #9644

postgresql

  • [postgresql] [bug] [regression]

    修复了 #9618 引起的严重回归问题,该问题修改了 2.0.10 的 insertmanyvalues 功能的架构,导致在使用 insertmanyvalues 功能以及 psycopg2 或 psycopg 驱动程序插入浮点值时,浮点值会丢失所有小数位。

    参考链接: #9701

mssql

  • [mssql] [bug]

    为 SQL Server 实现了 Double 类型,它将在 DDL 时渲染 DOUBLE PRECISION。 这是使用新的 MSSQL 数据类型 DOUBLE_PRECISION 实现的,该类型也可以直接使用。

oracle

  • [oracle] [bug]

    修复了 Oracle 数据库方言中的一个问题,当 Decimal 返回类型(例如 Numeric)的列在 Insert.returning() 子句中用于返回插入值时,会返回浮点数值,而不是 Decimal 对象。

2.0.10

发布日期:2023 年 4 月 21 日

orm

engine

  • [engine] [用例]

    添加了 create_pool_from_url()create_async_pool_from_url(),用于从作为字符串或 URL 传递的输入 URL 创建 Pool 实例。

    参考:#9613

  • [engine] [bug 修复]

    修复了在 2.0 系列中首次引入的 INSERT 语句的“插入多个值”行为 性能优化功能中发现的一个主要缺陷。这是 2.0.9 中更改的延续,该更改禁用了 SQL Server 版本的该功能,因为 ORM 依赖于表观行排序,而这并不能保证发生。此修复程序将新逻辑应用于所有“insertmanyvalues”操作,当 Insert.returning.sort_by_parameter_order 参数在 Insert.returning()UpdateBase.return_defaults() 方法中被使用时生效,该参数通过备用 SQL 形式、客户端参数的直接对应关系以及在某些情况下降级到逐行运行,将使用与每行中主键或其他唯一值的对应关系对每批返回的行进行排序,这些值可以与输入数据相关联。

    性能影响预计将是最小的,因为几乎所有常见的主键场景都适用于参数排序的批处理,以便在除 SQLite 之外的所有后端实现,而“逐行”模式的 Python 开销与 1.x 系列中使用的非常繁重的方法相比,开销极小。对于 SQLite,当使用“逐行”模式时,性能没有差异。

    预计通过高效的“逐行” INSERT 和 RETURNING 批处理功能,“insertmanyvalues”功能稍后可以更容易地推广到包含 RETURNING 支持但不一定容易保证与参数顺序对应的第三方后端。

    参考:#9603, #9618

typing

postgresql

  • [postgresql] [用例]

    在 asyncpg 方言中添加了 prepared_statement_name_func 连接参数选项。此选项允许传递一个可调用对象,用于自定义驱动程序在执行查询时将创建的预处理语句的名称。感谢 Pavel Sirotkin 的 pull request。

    参考:#9608

  • [postgresql] [用例]

    添加了缺失的 Range.intersection() 方法。感谢 Yurii Karabas 的 pull request。

    参考:#9509

  • [postgresql] [bug 修复]

    恢复了 ENUM.name 参数在 ENUM 签名中作为可选参数,因为它是从给定的 pep-435 Enum 类型自动选择的。

    参考:#9611

  • [postgresql] [bug 修复]

    修复了将 ENUM 与纯字符串进行比较时,会将右侧类型强制转换为 VARCHAR,由于添加到 asyncpg 等方言的更显式的强制转换,这将产生 PostgreSQL 类型不匹配错误的问题。

    参考:#9621

  • [postgresql] [bug 修复]

    修复了阻止 PostgreSQL 中表达式索引反射长表达式的问题。表达式被错误地截断为标识符长度(默认情况下为 63 字节)。

    参考:#9615

mssql

  • [mssql] [bug 修复]

    恢复了 Microsoft SQL Server 的 insertmanyvalues 功能。此功能在 2.0.9 版本中被禁用,原因是它明显依赖于 RETURNING 的排序,而这是无法保证的。“insertmanyvalues”功能的架构已得到改进,以适应 INSERT 语句和结果行处理的特定组织,从而可以保证返回行与输入记录的对应关系。

    参考:#9603, #9618

oracle

  • [oracle] [bug 修复]

    修复了 Uuid 数据类型无法在 Oracle 方言的 INSERT..RETURNING 子句中使用的问题。

2.0.9

发布日期:2023 年 4 月 5 日

orm

  • [orm] [bug 修复]

    修复了当使用“关系到别名类”功能,并且在加载器中指示递归 eager loader(例如 lazy="selectinload"),并结合另一侧的 eager loader 时可能发生的无限循环。循环检查已修复,以包括别名类关系。

    此更改也向后移植到:1.4.48

    参考:#9590

mariadb

  • [mariadb] [bug 修复]

    在 MariaDb 中添加了 row_number 作为保留字。

    参考:#9588

mssql

  • [mssql] [bug 修复]

    SQLAlchemy 的“insertmanyvalues”功能(允许快速 INSERT 多行,同时支持 RETURNING)已暂时禁用 SQL Server。由于单元工作目前依赖于此功能,以便将现有 ORM 对象与返回的主键标识匹配,因此这种特定的使用模式并非在所有情况下都适用于 SQL Server,因为 “OUTPUT inserted” 返回的行顺序可能并不总是与元组发送的顺序匹配,从而导致 ORM 对后续操作中的这些对象做出错误的决策。

    该功能将在即将发布的版本中重新启用,并将再次对多行 INSERT 语句生效,但是,除非 ORM 映射的表还包含“哨兵”列,以便可以将返回的行引用回原始传入数据,否则单元工作的该功能的使用将被禁用,可能对所有方言都是如此。

    参考:#9603

  • [mssql] [bug 修复]

    fast_executemany 设置为 True 时,更改了用于 SQL Server “executemany” 与 pyodbc 的批量 INSERT 策略,通过使用 fast_executemany / cursor.executemany() 进行不包含 RETURNING 的批量 INSERT,恢复了 SQLAlchemy 1.4 中设置此参数时使用的相同行为。

    来自最终用户的新性能详细信息表明,对于非常大的数据集,fast_executemany 仍然快得多,因为它使用 ODBC 命令,可以在单个往返中接收所有行,从而允许比 “insertmanyvalues” 发送的批次更大的数据大小,正如为 SQL Server 实现的那样。

    虽然此更改是为了使 “insertmanyvalues” 继续用于包含 RETURNING 的 INSERT,以及在未设置 fast_executemany 的情况下使用,但由于 #9603,“insertmanyvalues” 策略在任何情况下都已在 SQL Server 中全面禁用。

    参考:#9586

2.0.8

发布日期:2023 年 3 月 31 日

orm

  • [orm] [用例]

    当使用 MappedAsDataclass mixin 类或 registry.mapped_as_dataclass() 装饰器时,Python 数据类引发的异常(例如 TypeErrorValueError)现在被包装在 InvalidRequestError 包装器中,并附带有关于错误消息的翔实上下文,将 Python 数据类文档作为关于异常原因的权威背景信息来源。

    参考:#9563

  • [orm] [bug 修复]

    修复了 ORM 注解式声明中的一个问题,即使用递归类型(例如使用嵌套的 Dict 类型)将导致 ORM 注解解析逻辑中的递归溢出,即使此数据类型对于映射列不是必需的。

    参考:#9553

  • [orm] [bug 修复]

    修复了 mapped_column() 构造在声明式 mixin 上使用并包含 mapped_column.deferred 参数时会引发内部错误的问题。

    参考:#9550

  • [orm] [bug 修复]

    扩展了当声明式映射中存在纯 column() 对象时发出的警告,以包括任何未在适当的属性类型(例如 column_property()deferred() 等)中声明的任意 SQL 表达式。否则,这些属性根本未映射,并且在类字典中保持不变。由于似乎这种表达式通常不是预期的,因此现在针对所有此类被忽略的表达式发出警告,而不仅仅是 column() 的情况。

    参考:#9537

  • [orm] [bug 修复]

    修复了回归问题,其中访问未映射或尚未映射的类(例如在 declared_attr() 方法中调用它时)上的混合属性的表达式值将引发内部错误,因为对父类的映射器的内部获取将失败,并且在 2.0 中意外删除了忽略此失败的指令。

    参考:#9519

  • [orm] [bug 修复]

    在声明式 Mixin 上声明的字段,然后与使用 MappedAsDataclass 的类组合使用,其中这些 mixin 字段本身不是数据类的一部分,现在会发出弃用警告,因为这些字段将在未来的版本中被忽略,因为 Python 数据类的行为是忽略这些字段。类型检查器在 pep-681 下将看不到这些字段。

    参考:#9350

  • [orm] [bug 修复]

    修复了当在也具有与之关联的 ORM 注解的参数上调用 BindParameter.render_literal_execute() 方法时会失败的问题。实际上,在使用某些方言(例如 Oracle)以及使用 Select 构造(使用 Select.limit())以及某些 ORM 上下文(包括语句嵌入在关系 primaryjoin 表达式中)的 “FETCH FIRST” 时,这将表现为 SQL 编译失败。

    参考:#9526

  • [orm] [bug 修复]

    为了与针对 #5984#8862 所做的单元操作更改保持一致,这两项更改都禁用了 Session 进程中并非由属性访问触发的 “lazy=’raise’” 处理,Session.delete() 方法现在也会在遍历关系路径以处理 “delete” 和 “delete-orphan” 级联规则时禁用 “lazy=’raise’” 处理。 以前,对于设置了 “lazy=’raise’” 的对象,没有简单的方法可以通用地调用 Session.delete(),以便只加载必要的关系。“lazy=’raise’” 的主要目的是捕获在属性访问时发出的 SQL 加载,因此 Session.delete() 现在的行为与其他 Session 方法(包括 Session.merge() 以及 Session.flush() 以及 autoflush)类似。

    参考:#9549

  • [orm] [bug]

    修复了仅注释的 Mapped 指令无法在声明性 mixin 类中使用的问题,而不会导致该属性尝试对已在其超类上映射该属性的映射类的单继承或连接继承子类生效,从而产生冲突的列错误和/或警告。

    参考:#9564

  • [orm] [bug] [typing]

    正确地为 Insert.from_select.names 类型注解,使其接受字符串列表、列或映射属性。

    参考:#9514

示例

  • [examples] [bug]

    修复了 “版本化历史记录” 示例中,使用从 DeclarativeBase 派生的声明性基类将无法映射的问题。 此外,修复了给定的测试套件,以便现在可以使用 Python unittest 再次运行示例的文档说明。

类型注解

postgresql

  • [postgresql] [bug]

    修复了 PostgreSQL 方言(如 asyncpg)中的严重回归,这些方言依赖于 SQL 中的显式转换,以便将数据类型正确传递给驱动程序,其中 String 数据类型将与正在比较的确切列长度一起转换,导致在将较小长度的 VARCHAR 与更长长度的字符串进行比较时发生隐式截断,而与使用的运算符(例如 LIKE、MATCH 等)无关。 PostgreSQL 方言现在在渲染这些转换时从 VARCHAR 中省略长度。

    参考:#9511

mysql

  • [mysql] [bug]

    修复了无法使用显式长度零生成字符串数据类型(如 CHARVARCHARTEXT)以及二进制 BLOB 的问题,这对于 MySQL 具有特殊含义。拉取请求由 J. Nick Koston 提供。

    参考:#9544

misc

  • [bug] [util]

    在 OrderedSet 类中实现了缺失的方法 copypop

    参考:#9487

2.0.7

发布日期:2023 年 3 月 18 日

类型注解

  • [typing] [bug]

    修复了 composite() 不允许任意可调用对象作为复合类源的类型注解问题。

    参考:#9502

postgresql

  • [postgresql] [usecase]

    添加了新的 PostgreSQL 类型 CITEXT。拉取请求由 Julian David Rath 提供。

    参考:#9416

  • [postgresql] [usecase]

    修改了基础 PostgreSQL 方言,以更好地与 SQLAlchemy 2.0 的 sqlalchemy-redshift 第三方方言集成。拉取请求由 matthewgdv 提供。

    参考:#9442

2.0.6

发布日期:2023 年 3 月 13 日

orm

  • [orm] [bug]

    修复了 “活动历史记录” 功能未完全为复合属性实现的错误,导致无法接收包含 “旧” 值的事件。 这似乎在较旧的 SQLAlchemy 版本中也是如此,其中 “active_history” 会传播到基础的基于列的属性,但是即使 composite() 设置为 active_history=True,侦听复合属性本身的事件处理程序也不会获得被替换的 “旧” 值。

    此外,修复了一个 2.0 本地回归,该回归禁止将复合属性上的 active_history 分配给具有 attr.impl.active_history=True 的 impl。

    参考:#9460

  • [orm] [bug]

    修复了在 cython 和纯 Python 实现的 Row 之间 pickle Python 行的回归,这是作为版本 2.0 类型注解的重构代码的一部分发生的。 特定的常量在纯 Python 版本的 Row 中变成了基于字符串的 Enum,而 cython 版本继续使用整数常量,导致反序列化失败。

    参考:#9418

sql

  • [sql] [bug] [regression]

    修复了 #8098 的回归,该回归在 1.4 系列中发布,并为 lambda SQL API 提供了一层并发安全检查,其中补丁中包含的其他修复程序未能应用于主分支。 这些其他修复程序已应用。

    参考:#9461

  • [sql] [bug]

    修复了当 select() 构造未给定任何列,然后在 EXISTS 的上下文中使用时,将无法渲染并引发内部异常的回归。 虽然空的 “SELECT” 通常不是有效的 SQL,但在 EXISTS 的上下文中,PostgreSQL 等数据库允许它,并且无论如何,该条件现在不再引发内部异常。

    参考:#9440

类型注解

oracle

  • [oracle] [bug]

    修复了 Oracle “名称规范化” 对于 “PUBLIC” 模式中的符号(例如同义词)的反射无法正确工作的问题,这意味着 PUBLIC 名称在 Python 端对于 Table.schema 参数无法指示为小写。 使用大写 “PUBLIC” 可以工作,但会导致笨拙的 SQL 查询,包括带引号的 "PUBLIC" 名称以及在索引表时使用大写 “PUBLIC”,这不一致。

    参考:#9459

2.0.5.post1

发布日期:2023 年 3 月 5 日

orm

  • [orm] [bug]

    为内置映射集合类型(包括 KeyFuncDictattribute_keyed_dict()column_keyed_dict())添加了构造函数参数,以便可以就地构造这些字典类型,并预先给出数据;这为与 Python dataclasses .asdict() 等工具提供了进一步的兼容性,后者依赖于直接将这些类作为普通字典类调用。

    参考:#9418

  • [orm] [bug] [regression]

    修复了由于 #8372 导致的多个回归,涉及 attribute_mapped_collection()(现在称为 attribute_keyed_dict())。

    首先,该集合不再可用于本身不是普通映射属性的 “key” 属性;已修复链接到描述符和/或关联代理属性的属性。

    其次,如果事件或其他操作需要访问 “key” 以便从未加载的映射属性填充字典,这也将不适当地引发错误,而不是像 1.4 中的行为那样尝试加载属性。 这也已修复。

    对于这两种情况,#8372 的行为已扩展。#8372 引入了一个错误,当将用作映射字典键的派生键实际上未分配时,会引发该错误。 在此更改中,仅当 “.key” 属性的有效值为 None 时才会发出警告,其中无法明确确定此 None 是否是有意的。None 将来将不支持作为映射集合字典键(因为它通常指 NULL,这意味着 “未知”)。 设置 attribute_keyed_dict.ignore_unpopulated_attribute 现在也将导致忽略此类 None 键。

    参考:#9424

  • [orm] [bug]

    已确定 sqlitemssql+pyodbc 方言现在与 SQLAlchemy ORM 的 “版本化行” 功能兼容,因为 SQLAlchemy 现在通过计算返回的行数来计算此特定情况下 RETURNING 语句的 rowcount,而不是依赖于 cursor.rowcount。 特别是,ORM 版本化行用例(文档位于 配置版本计数器)现在应完全支持 SQL Server pyodbc 方言。

  • [orm] [bug]

    添加了对应用于深度超过一级的继承层次结构中每个映射器的 Mapper.polymorphic_load 参数的支持,允许使用单个语句加载层次结构中指示 "selectin" 的所有类的列,而不是忽略中间类上的元素,这些中间类仍然指示它们也将参与 "selectin" 加载,并且不是最基础的 SELECT 语句的一部分。

    参考:#9373

  • [orm] [bug]

    继续修复 #8853,允许完全限定 Mapped 名称,无论是否存在 from __annotations__ import future。 此问题首先在 2.0.0b3 中修复,并通过测试套件确认了这种情况有效,但是测试套件显然没有测试名称 Mapped 根本不存在的行为;字符串解析已更新,以确保 Mapped 符号可以被定位,这适用于 ORM 如何使用这些函数。

    参考:#8853, #9335

orm 声明式

  • [bug] [orm declarative]

    修复了如果两个同名列在属性名称与显式给列本身指定的名称不同时映射,则新的 mapped_column.use_existing_column 功能将无法工作的问题。 使用此参数时,属性名称现在可以不同命名。

    参考:#9332

engine

  • [engine] [performance]

    Result 的 Cython 实现进行了一个小的优化,使用 cdef 来表示特定的整数值,以避免 Python 开销。拉取请求由 Matus Valo 提供。

    参考:#9343

  • [engine] [bug]

    修复了由于意外依赖于不稳定的哈希值,导致 Row 对象无法跨进程可靠地 unpickle 的错误。

    参考:#9423

sql

schema

类型注解

  • [typing] [usecase]

    使用新的公共类型 QueryPropertyDescriptor 导出了由 scoped_session.query_property() 返回的类型。

    参考:#9338

  • [typing] [bug]

    修复了 Connection.scalars() 方法的类型注解问题,该方法未注解为允许使用多参数列表,现在通过 insertmanyvalues 操作支持该功能。

  • [typing] [bug]

    改进了传递给 Insert.values()Update.values() 的映射的类型注解,使其对集合类型更加开放,通过指示只读 Mapping 而不是可写 Dict,后者会在密钥类型过于受限时出错。

    参考:#9376

  • [typing] [bug]

    Numeric 类型对象添加了缺失的 init 重载,以便 pep-484 类型检查器可以正确解析完整类型,从 Numeric.asdecimal 参数派生,无论将表示 Decimal 对象还是 float 对象。

    参考:#9391

  • [typing] [bug]

    修复了 Select.from_statement() 不接受 text()TextualSelect 对象作为有效类型的类型注解错误。 此外,修复了 columns 方法使其具有返回类型,之前该类型缺失。

    参考:#9398

  • [typing] [bug]

    修复了 with_polymorphic() 未正确记录类类型的类型注解问题。

    参考:#9340

postgresql

  • [postgresql] [bug]

    修复了 PostgreSQL ExcludeConstraint 中文字值被编译为绑定参数而不是 DDL 所需的直接内联值的问题。

    参考:#9349

  • [postgresql] [bug]

    修复了如果约束包含文本表达式元素,PostgreSQL ExcludeConstraint 构造在 Table.to_metadata() 等操作以及某些 Alembic 场景中不可复制的问题。

    参考:#9401

mysql

  • [mysql] [bug] [postgresql]

    在 2.0.0b1 中为 #5648 添加的池 ping 侦听器以通过 DialectEvents.handle_error() 事件接收异常事件的支持未能考虑到特定于方言的 ping 例程,例如 MySQL 和 PostgreSQL 的 ping 例程。 方言功能已重新设计,以便所有方言都参与事件处理。 此外,添加了一个新的布尔元素 ExceptionContext.is_pre_ping,用于标识此操作是否发生在预 ping 操作中。

    对于此版本,实现自定义 Dialect.do_ping() 方法的第三方方言可以通过使其方法不再捕获异常或检查异常是否为 “is_disconnect” 来选择加入新改进的行为,而是仅将所有异常向外传播。 现在由默认方言上的封闭方法完成检查异常是否为 “is_disconnect”,这确保在将异常测试为 “disconnect” 异常之前,为所有异常场景调用事件挂钩。 如果现有的 do_ping() 方法继续捕获异常并检查 “is_disconnect”,它将继续像以前一样工作,但如果 handle_error 挂钩未向外传播异常,则将无法访问该异常。

    参考文献: #5648

sqlite

  • [sqlite] [bug] [回归]

    修复了 SQLite 连接的回归问题,即在建立数据库函数时使用 deterministic 参数对于旧版本的 SQLite(版本低于 3.8.3)会失败。已改进版本检查逻辑以适应这种情况。

    参考文献: #9379

mssql

  • [mssql] [bug]

    修复了新的 Uuid 数据类型与 pymssql 驱动程序不兼容的问题。由于 pymssql 似乎再次得到维护,因此恢复了对 pymssql 的测试支持。

    参考文献: #9414

  • [mssql] [bug]

    调整了 pymssql 方言,以更好地利用 INSERT 语句的 RETURNING 子句来检索最后插入的主键值,这与当前的 mssql+pyodbc 方言的行为方式相同。

misc

  • [bug] [ext]

    修复了 automap 中的问题,即从特定的映射类而不是直接从 AutomapBase 调用 AutomapBase.prepare() 时,在 automap 检测到新表时不会使用正确的基类,而是使用给定的类,导致映射器尝试配置继承。虽然在任何情况下都应该从基类调用 AutomapBase.prepare(),但从子类调用时不应该表现得如此糟糕。

    参考文献: #9367

  • [bug] [ext] [回归]

    修复了由 #8667sqlalchemy.ext.mutable 添加类型提示导致的回归问题,其中 .pop() 方法的语义发生了变化,导致该方法无法工作。感谢 Nils Philippsen 提供的拉取请求。

    参考文献: #9380

2.0.4

发布日期:2023 年 2 月 17 日

orm

  • [orm] [用例]

    为了适应 SQLAlchemy 2.0 中 ORM Declarative 使用的列排序的更改,添加了一个新的参数 mapped_column.sort_order,可用于控制 ORM 在表中定义的列的顺序,适用于常见的用例,例如混合类中使用的主键列应首先出现在表中。 ORM Declarative 应用不同的列顺序;使用 sort_order 控制行为 中的更改说明阐述了默认的排序行为更改(这是所有 SQLAlchemy 2.0 版本的一部分)以及在使用混合类和多个类时如何使用 mapped_column.sort_order 来控制列顺序(2.0.4 中的新功能)。

    参考文献: #9297

  • [orm] [用例]

    Session.refresh() 方法现在将立即加载在 Session.refresh.attribute_names 集合中显式命名的关系绑定属性,即使它当前链接到“select”加载器,而“select”加载器通常是“lazy”加载器,在刷新期间不会触发。 “lazy 加载器”策略现在将检测到该操作是用户显式发起的 Session.refresh() 操作,并且显式命名了这个属性,然后将调用 “immediateload” 策略来实际发出 SQL 以加载该属性。这在某些 asyncio 情况下特别有用,在这些情况下,必须强制加载未加载的 lazy 加载属性,而不能使用 asyncio 中不支持的实际 lazy-loading 属性模式。

    参考文献: #9298

  • [orm] [bug] [回归]

    修复了 2.0.2 版本中由于 #9217 引入的回归问题,其中使用 DML RETURNING 语句以及 Select.from_statement() 构造(如 #9217 中“修复”的那样)与使用表达式(例如 column_property())的 ORM 映射类结合使用时,会导致 Core 内部错误,其中它会尝试按名称匹配表达式。此修复程序修复了 Core 问题,并调整了 #9217 中的修复程序,使其不对 DML RETURNING 用例生效,因为它会增加不必要的开销。

    参考文献: #9273

  • [orm] [bug]

    将内部 EvaluatorCompiler 模块标记为 ORM 私有,并将其重命名为 _EvaluatorCompiler。对于可能依赖于此模块的用户,名称 EvaluatorCompiler 仍然存在,但是不支持这种用法,并且将在未来的版本中删除。

orm declarative

  • [用例] [orm declarative]

    MappedAsDataclass 类和 registry.mapped_as_dataclass() 方法添加了新的参数 dataclasses_callable,该参数允许使用 Python dataclasses.dataclass 的替代可调用对象来生成数据类。这里的用例是替换为 Pydantic 的数据类函数。 对版本 2.0.1 中为 #9179 添加的混入支持进行了调整,以便重写混入的 __annotations__ 集合,使其不包含 Mapped 容器,这与映射类的情况相同,以便 Pydantic 数据类构造函数不会暴露于未知类型。

    参考文献: #9266

sql

  • [sql] [bug]

    修复了当比较使用 ColumnOperators.in_() 运算符时,元组值的元素类型会被硬编码为采用被比较元组的类型的问题。 这与通常确定二元表达式类型的方式不一致,通常是首先考虑右侧的实际元素类型,然后再应用左侧类型。

    参考文献: #9313

  • [sql]

    添加了公共属性 Table.autoincrement_column,该属性返回列中标识为自动递增的列。

    参考文献: #9277

typing

  • [typing] [用例]

    改进了对 Hybrid Attributes 扩展的类型支持,更新了所有文档以使用 ORM Annotated Declarative 映射,并添加了一个名为 hybrid_property.inplace 的新修饰符。 此修饰符提供了一种就地更改 hybrid_property 状态的方法,这本质上是 SQLAlchemy 1.2.0 版本之前早期版本的 hybrid 所做的事情,#3912 将此更改为移除就地修改。 现在,选择性启用地恢复了这种就地修改,以允许单个 hybrid 设置多个方法,而无需将所有方法命名为相同名称,也无需小心地“链接”不同名称的方法以保持组合。 诸如 Mypy 和 Pyright 之类的类型检查工具不允许类上存在同名方法,因此通过此更改,恢复了一种使用类型支持设置 hybrid 的简洁方法。

    参考文献: #9321

oracle

  • [oracle] [bug]

    调整了 python-oracledb 方言的 thick_mode 参数的行为,以正确接受 False 作为值。 之前,只有 None 表示应禁用 thick 模式。

    参考文献: #9295

2.0.3

发布日期:2023 年 2 月 9 日

sql

  • [sql] [bug] [回归]

    修复了 2.0 系列中 SQL 表达式公式中的严重回归问题,该问题是由于 #7744 改进了对针对同一运算符重复包含多个元素的 SQL 表达式的支持;对于前两个元素之后的表达式元素,括号分组将丢失。

    参考文献: #9271

typing

  • [typing] [bug]

    移除了 typing.Self 解决方法,现在对于大多数返回 Self 的方法使用 PEP 673。 由于此更改,现在需要 mypy>=1.0.0 才能对 SQLAlchemy 代码进行类型检查。 感谢 Yurii Karabas 提供的拉取请求。

    参考文献: #9254

2.0.2

发布日期:2023 年 2 月 6 日

orm

  • [orm] [用例]

    添加了新的事件钩子 MapperEvents.after_mapper_constructed(),它提供了一个事件钩子,在 Mapper 对象完全构建之后,但在 registry.configure() 调用之前发生。 这允许代码根据 Mapper 的初始配置创建其他映射和表结构,这也集成在 Declarative 配置中。 之前,当使用 Declarative 时,在类创建过程中创建 Mapper 对象,没有记录的方法可以在此时运行代码。 此更改是为了立即惠及自定义映射方案,例如 具有历史记录表的版本控制 示例,该示例生成额外的映射器和表以响应映射类的创建。

    参考文献: #9220

  • [orm] [用例]

    不常用的 Mapper.iterate_properties 属性和 Mapper.get_property() 方法(主要在内部使用)不再隐式调用 registry.configure() 进程。 公共访问这些方法的情况非常罕见,并且具有 registry.configure() 的唯一好处是允许 “backref” 属性出现在这些集合中。 为了支持新的 MapperEvents.after_mapper_constructed() 事件,现在可以迭代和访问内部 MapperProperty 对象,而无需触发映射器本身的隐式配置。

    更面向公共的迭代所有映射器属性的途径,Mapper.attrs 集合和类似的集合,仍然会隐式调用 registry.configure() 步骤,从而使 backref 属性可用。

    在所有情况下,registry.configure() 始终可以被直接调用。

    参考文献: #9220

  • [orm] [bug] [回归]

    修复了由 #8705 引起的晦涩的 ORM 继承问题,其中继承映射器的一些场景(指示来自本地表和继承表的列组一起在 column_property() 下)仍然会警告说,具有相同名称的属性正在被隐式组合。

    参考文献: #9232

  • [orm] [bug] [回归]

    修复了回归问题,其中对于不支持“RETURNING”的“rowcount”的 SQLite 和其他数据库,将 Mapper.version_id_col 功能与常规 Python 端递增列一起使用会失败,因为即使实际情况并非如此,也会为这些列假定“RETURNING”。

    参考文献: #9228

  • [orm] [bug] [回归]

    修复了在 ORM 上下文中使用 Select.from_statement() 时的回归问题,其中对于非完全文本的 ORM 语句,基于名称单独将列匹配到 SQL 标签的功能被禁用。 这将阻止具有列名标签的任意 SQL 表达式与要加载的实体匹配,而这在 1.4 和以前的系列中是有效的,因此已恢复以前的行为。

    参考文献: #9217

orm declarative

  • [bug] [orm declarative]

    修复了由 #9171 的修复程序引起的回归问题,该修复程序本身正在修复一个回归问题,涉及从 DeclarativeBase 扩展的类上的 __init__() 的机制。 此更改使得如果类上没有直接的 __init__() 方法,则将 __init__() 应用于用户定义的基类。 已对此进行调整,以便仅当用户定义的基类的层次结构中没有其他类具有 __init__() 方法时才应用 __init__()。 这再次允许基于 DeclarativeBase 的用户定义的基类包含混入,这些混入本身包含自定义的 __init__() 方法。

    参考文献: #9249

  • [bug] [orm declarative]

    修复了 ORM Declarative Dataclass 映射中的问题,该问题与 2.0.1 中通过 #9179 添加的对混入的新增支持有关,其中在某些情况下,使用混入和 ORM 继承的组合会错误地分类字段,导致字段级数据类参数(例如 init=False)丢失。

    参考文献: #9226

  • [bug] [orm declarative]

    修复了 ORM Declarative 映射,以允许在使用 mapped_column() 时,在 __mapper_args__ 中指定 Mapper.primary_key 参数。 尽管此用法直接在 2.0 文档中,但 Mapper 未在此上下文中接受 mapped_column() 构造。 此功能已适用于 Mapper.version_id_colMapper.polymorphic_on 参数。

    作为此更改的一部分,可以在非映射混入类上指定 __mapper_args__ 属性,而无需使用 declared_attr(),包括引用混入中本地存在的 Columnmapped_column() 对象的 "primary_key" 条目; Declarative 也会将这些列转换为特定映射类的正确列。 同样,这已经适用于 Mapper.version_id_colMapper.polymorphic_on 参数。 此外,"primary_key" 中的元素可以指示为现有映射属性的字符串名称。

    参考文献: #9240

  • [bug] [orm declarative]

    如果映射尝试在同一类层次结构中混合使用 MappedAsDataclassregistry.mapped_as_dataclass(),则会引发显式错误,因为这会导致数据类函数在错误的时间应用于映射类,从而导致映射过程中出现错误。

    参考文献: #9211

examples

sql

  • [sql] [用例]

    添加了一整套新的 SQL 位运算符,用于对适当的数据值(例如整数、位字符串和类似值)执行数据库端位表达式。 感谢 Yegor Statkevich 提供的拉取请求。

    另请参阅

    位运算符

    参考文献: #8780

asyncio

  • [asyncio] [bug]

    修复了由 #8419 的修复程序引起的回归问题,该问题导致 asyncpg 连接在连接未显式返回到连接池并且被 Python 垃圾回收拦截的情况下被重置(即调用事务 rollback())并正常返回到池,如果垃圾回收操作在 asyncio 事件循环之外被调用,则会导致失败,从而导致大量堆栈跟踪活动转储到日志和标准输出中。

    恢复了正确的行为,即所有由于未显式返回到连接池而被垃圾回收的 asyncio 连接都将从池中分离并丢弃,并发出警告,而不是返回到池中,因为它们无法可靠地重置。 对于 asyncpg 连接,asyncpg 特定的 terminate() 方法将用于在此过程中更优雅地结束连接,而不是直接丢弃它。

    此更改包括一个小的行为更改,有望对调试 asyncio 应用程序有用,其中在 asyncio 连接意外被垃圾回收的情况下发出的警告已通过将其移出 try/except 块并移入 finally: 块而变得稍微更具侵略性,在 finally: 块中,无论 detach/termination 操作是否成功,它都将无条件地发出。 它还将具有以下效果:将 Python 警告提升为异常的应用程序或测试套件会将此视为完全异常引发,而以前此警告实际上不可能作为异常传播。 需要临时容忍此警告的应用程序和测试套件应调整 Python 警告过滤器,以允许这些警告不引发异常。

    传统同步连接的行为保持不变,垃圾回收的连接继续正常返回到池中,而不会发出警告。 这可能会在未来的主要版本中更改,至少会发出与为 asyncio 驱动程序发出的类似警告,因为对于池化连接,被垃圾回收拦截而未正确返回到池中是使用错误。

    参考文献: #9237

mysql

  • [mysql] [bug] [回归]

    修复了由问题 #9058 引起的回归问题,该问题调整了 MySQL 方言的 has_table() 以再次使用 “DESCRIBE”,其中使用不存在的模式名称时 MySQL 版本 8 引发的特定错误代码是意外的,并且未能被解释为布尔结果。

    参考文献: #9251

  • [mysql] [bug]

    添加了对 MySQL 8 新的 AS <name> ON DUPLICATE KEY 语法在使用 Insert.on_duplicate_key_update() 时的支持,这是较新版本的 MySQL 8 所必需的,因为以前使用 VALUES() 的语法现在在这些版本中会发出弃用警告。 采用服务器版本检测来确定应使用传统的 MariaDB / MySQL < 8 VALUES() 语法,还是较新的 MySQL 8 所需的语法。 感谢 Caspar Wylie 提供的拉取请求。

    参考文献: #8626

sqlite

  • [sqlite] [bug]

    修复了 SQLite 方言的 has_table() 函数,使其能够正确报告当查询包含一个非空的模式名称,且该模式不存在时返回 False;此前,会引发数据库错误。

    参考文献: #9251

2.0.1

发布日期:2023 年 2 月 1 日

orm

  • [orm] [bug] [回归]

    修复了回归错误,该错误导致使用连接表继承和复合外键的 ORM 模型会在映射器内部遇到内部错误。

    参考:#9164

  • [orm] [bug]

    改进了错误报告,当从基类链接策略选项到子类上的另一个属性时,应使用 of_type()。此前,当使用 Load.options() 时,消息会缺乏信息性细节,说明应使用 of_type(),而直接链接选项时则不会出现这种情况。即使使用 Load.options(),现在也会发出信息性细节。

    参考:#9182

orm declarative

  • [bug] [orm declarative]

    添加了对 PEP 484 NewType 的支持,可在 registry.type_annotation_map 以及 Mapped 构造中使用。这些类型的行为方式与当前的自定义类型子类相同;它们必须显式出现在 registry.type_annotation_map 中才能被映射。

    参考:#9175

  • [bug] [orm declarative]

    当使用 MappedAsDataclass 超类时,层次结构中作为此类的子类的所有类现在都将通过 @dataclasses.dataclass 函数运行,无论它们是否实际被映射,以便在层次结构中未映射的类上声明的非 ORM 字段将在映射的子类转换为数据类时使用。此行为适用于使用 __abstract__ = True 映射的中间类,以及用户定义声明性基类本身,假设 MappedAsDataclass 作为这些类的超类存在。

    这允许在超类上使用非映射属性,例如 InitVar 声明,而无需在每个未映射的类上显式运行 @dataclasses.dataclass 装饰器。新行为被认为是正确的,因为这是 PEP 681 实现在使用超类指示数据类行为时的预期。

    参考:#9179

  • [bug] [orm declarative]

    添加了对 PEP 586 Literal[] 的支持,可在 registry.type_annotation_map 以及 Mapped 构造中使用。要使用此类自定义类型,它们必须显式出现在 registry.type_annotation_map 中才能被映射。感谢 Frederik Aalund 的 pull request。

    作为此更改的一部分,registry.type_annotation_map 中对 Enum 的支持已扩展为包括对 Literal[] 类型的支持,该类型由字符串值组成,除了 enum.Enum 数据类型之外。如果在 Mapped[] 中使用了 Literal[] 数据类型,但未在 registry.type_annotation_map 中链接到特定数据类型,则默认情况下将使用 Enum

    参考:#9187

  • [bug] [orm declarative]

    修复了在 registry.type_annotation_map 中使用 Enum 时出现的问题,其中 Enum.native_enum 参数不会正确复制到映射的列数据类型,如果按照文档中所述将其覆盖为 False。

    参考:#9200

  • [bug] [orm declarative] [回归]

    修复了 DeclarativeBase 类中的回归错误,其中注册表的默认构造函数不会应用于基类本身,这与之前的 declarative_base() 构造的工作方式不同。这将阻止具有自己的 __init__() 方法的映射类调用 super().__init__() 以访问注册表的默认构造函数并自动填充属性,而是命中 object.__init__(),这将对任何参数引发 TypeError

    参考:#9171

  • [bug] [orm declarative]

    改进了用于解释 PEP 593 Annotated 类型在 Annotated Declarative 映射中使用的规则集,将检查内部类型是否为 “Optional”,这将添加到列是否设置为 “nullable” 的标准中;如果 Annotated 容器中的类型是可选的(或与 None 联合),则在没有显式的 mapped_column.nullable 参数覆盖它的情况下,该列将被视为可为空。

    参考:#9177

sql

  • [sql] [bug]

    修正了版本 2.0.0 中发布的 #7664 的修复,也包括了 DropSchema,该修复中无意遗漏了它,从而允许在没有方言的情况下进行字符串化。这两个构造的修复已反向移植到 1.4 系列,版本为 1.4.47。

    参考:#7664

  • [sql] [bug] [回归]

    修复了与新的 “insertmanyvalues” 功能实现相关的回归错误,其中当 insert() 通过 CTE 在另一个 insert() 内部被引用时,会发生内部 TypeError;当使用 “insertmanyvalues” 时,对 asyncpg 等位置方言的这种用例进行了额外的修复。

    参考:#9173

typing

2.0.0

发布日期:2023 年 1 月 26 日

orm

  • [orm] [bug]

    改进了在配置映射器或刷新过程中发出的警告通知,这些警告通常作为不同操作的一部分被调用,为消息添加了额外的上下文,表明这些操作之一是警告的来源,这些操作可能与表面上无关的操作有关。

    参考:#7305

orm extensions

  • [feature] [orm extensions]

    为水平分片 API set_shard_id 添加了新选项,该选项设置要查询的有效分片标识符,用于主查询以及所有辅助加载器,包括关系急切加载器以及关系和列延迟加载器。

    参考:#7226

  • [usecase] [orm extensions]

    AutomapBase 添加了新功能,用于跨可能具有重叠名称的多个模式自动加载类,通过提供 AutomapBase.prepare.modulename_for_table 参数,该参数允许自定义新生成的类的 __module__ 属性,以及一个新的集合 AutomapBase.by_module,它存储模块名称的点分隔命名空间,这些模块名称基于 __module__ 属性链接到类。

    此外,现在可以多次调用 AutomapBase.prepare() 方法,无论是否启用反射;每次调用只会处理之前未映射的新添加的表。此前,需要每次显式调用 MetaData.reflect() 方法。

    另请参阅

    从多个模式生成映射 - 说明了同时使用这两种技术。

    参考:#5145

sql

  • [sql] [bug]

    修复了 CreateSchema DDL 构造的字符串化,当在没有方言的情况下进行字符串化时,会失败并出现 AttributeError。更新:请注意,此修复未能适应 DropSchema;版本 2.0.1 中的后续修复解决了这种情况。这两个元素的修复已反向移植到 1.4.47。

    参考:#7664

typing

  • [typing] [bug]

    为内置的泛型函数添加了类型标注,这些函数可从 func 命名空间获得,它们接受一组特定的参数并返回特定的类型,例如 countcurrent_timestamp 等。

    参考:#9129

  • [typing] [bug]

    更正了为 “lambda 语句” 传递的类型,以便 mypy、pyright 和其他工具可以接受普通的 lambda,而不会出现关于参数类型的任何错误。此外,还为 lambda 语句的更多公共 API 实现了类型标注,并确保 StatementLambdaElementExecutable 层次结构的一部分,因此它被类型标注为 Connection.execute() 所接受。

    参考:#9120

  • [typing] [bug]

    ColumnOperators.in_()ColumnOperators.not_in() 方法的类型标注包括 Iterable[Any] 而不是 Sequence[Any],以获得参数类型方面的更大灵活性。

    参考:#9122

  • [typing] [bug]

    从类型标注的角度来看,or_()and_() 函数要求第一个参数必须存在,但是这些函数仍然接受零个参数,这将在运行时发出弃用警告。类型标注也已添加,以支持发送固定的字面量 False 用于 or_()True 用于 and_() 作为仅第一个参数,但是文档现在指出在这些情况下发送 false()true() 构造是一种更明确的方法。

    参考:#9123

  • [typing] [bug]

    修复了类型标注问题,其中迭代 Query 对象时类型标注不正确。

    参考:#9125

  • [typing] [bug]

    修复了类型标注问题,其中将 Result 用作上下文管理器时的对象类型未被保留,在所有情况下都指示 Result,而不是特定的 Result 子类型。感谢 Martin Baláž 的 pull request。

    参考:#9136

  • [typing] [bug]

    修复了当使用 relationship.remote_side 和类似参数时,传递类型为 Mapped 的带注释的声明性对象,类型检查器不会接受的问题。

    参考:#9150

  • [typing] [bug]

    为旧式运算符添加了类型标注,例如 isnot()notin_() 等,这些运算符之前引用了较新的运算符,但本身未进行类型标注。

    参考:#9148

postgresql

  • [postgresql] [bug]

    为 asyncpg 方言添加了支持,以便在 SELECT 语句可用时返回 cursor.rowcount 值。虽然这不是 cursor.rowcount 的典型用法,但其他 PostgreSQL 方言通常会提供此值。感谢 Michael Gorven 的 pull request。

    此更改也已反向移植到:1.4.47

    参考:#9048

mysql

  • [mysql] [usecase]

    为 MySQL 索引反射添加了支持,以正确反射 mysql_length 字典,此前该字典被忽略。

    此更改也已反向移植到:1.4.47

    参考:#9047

mssql

  • [mssql] [bug] [回归]

    MSSQL 方言新添加的注释反射和渲染功能(在 #7844 中添加)现在默认情况下将被禁用,如果无法确定可能正在使用不受支持的后端(例如 Azure Synapse);此后端不支持表和列注释,也不支持用于生成和反射它们的 SQL Server 例程。方言中添加了一个新参数 supports_comments,默认值为 None,表示应自动检测注释支持。当设置为 TrueFalse 时,注释支持将被无条件地启用或禁用。

    另请参阅

    DDL 注释支持

    参考:#9142

2.0.0rc3

发布日期:2023 年 1 月 18 日

orm

  • [orm] [feature]

    Mapper 添加了一个名为 Mapper.polymorphic_abstract 的新参数。此指令的目的是使 ORM 不会将该类视为直接实例化或加载,而仅视为子类。实际效果是 Mapper 将阻止直接实例化该类的实例,并期望该类没有配置不同的多态标识。

    在实践中,使用 Mapper.polymorphic_abstract 映射的类可以用作 relationship() 的目标,也可以在查询中使用;子类当然必须在其映射中包含多态标识。

    新参数自动应用于子类化 AbstractConcreteBase 类的类,因为此类不打算被实例化。

    参考:#9060

  • [orm] [bug]

    修复了在 registry.type_annotation_map 中使用 pep-593 Annotated 类型的问题,该类型本身包含泛型普通容器或 collections.abc 类型(例如 listdictcollections.abc.Sequence 等)作为目标类型,当 ORM 尝试解释 Annotated 实例时,会产生内部错误。

    参考:#9099

  • [orm] [bug]

    relationship() 针对抽象容器类型(例如 Mapped[Sequence[B]])进行映射时,添加了一条错误消息,而没有提供 relationship.container_class 参数,当类型为抽象类型时,这是必需的。此前,抽象容器会在稍后的步骤尝试实例化并失败。

    参考:#9100

sql

  • [sql] [bug]

    修复了错误/回归,其中在仅限 2.0 的 UpdateUpdate.values() 方法和 InsertInsert.values() 方法中使用与 bindparam() 同名的列时,在某些情况下会静默失败,无法遵守其中呈现参数的 SQL 表达式,而是用同名的新参数替换表达式,并丢弃 SQL 表达式的其他元素,例如 SQL 函数等。具体情况是针对 ORM 实体而不是普通 Table 实例构建的语句,但如果使用 SessionConnection 调用语句,则会发生这种情况。

    Update 部分问题在 2.0 和 1.4 版本中均存在,并且已向后移植到 1.4 版本。

    此更改也已反向移植到:1.4.47

    参考链接: #9075

类型标注

  • [类型标注] [错误修复]

    修复了 sqlalchemy.ext.hybrid 扩展中注解的错误,以更有效地对用户自定义方法进行类型标注。 类型标注现在使用 PEP 612 功能(现在受新版本的 Mypy 支持),以维护 hybrid_method 的参数签名。 混合方法的返回值在 Select.where() 等上下文中被接受为 SQL 表达式,同时仍然支持 SQL 方法。

    参考链接: #9096

mypy

  • [mypy] [错误修复]

    调整了 mypy 插件,以适应在使用 SQLAlchemy 1.4 时,针对问题 #236 sqlalchemy2-stubs 所做的一些潜在更改。 这些更改在 SQLAlchemy 2.0 中保持同步。 这些更改也向后兼容旧版本的 sqlalchemy2-stubs。

    此更改也已反向移植到:1.4.47

  • [mypy] [错误修复]

    修复了 mypy 插件中的崩溃问题,该问题可能在 1.4 和 2.0 版本中发生,如果 mapped() 装饰器的装饰器在具有两个以上组件的表达式中被引用(例如 @Backend.mapper_registry.mapped)。 现在已忽略这种情况; 当使用插件时,装饰器表达式需要是两个组件(即 @reg.mapped)。

    此更改也已反向移植到:1.4.47

    参考链接: #9102

postgresql

  • [postgresql] [错误修复]

    修复了回归问题,其中 psycopg3 从 3.1.8 版本开始更改了 API 调用,以期望特定的对象类型,而以前没有强制执行该类型,从而破坏了 psycopg3 方言的连接性。

    参考链接: #9106

oracle

  • [oracle] [用例]

    添加了对 Oracle SQL 类型 TIMESTAMP WITH LOCAL TIME ZONE 的支持,使用新添加的 Oracle 特定的 TIMESTAMP 数据类型。

    参考链接: #9086

2.0.0rc2

发布日期:2023 年 1 月 9 日

orm

  • [orm] [错误修复]

    修复了 2.0 中添加的过度限制性的 ORM 映射规则问题,该规则阻止了针对 TableClause 对象(例如 wiki 上的视图配方中使用的对象)的映射。

    参考链接: #9071

类型标注

  • [类型标注] [错误修复]

    在 PEP 681 的已接受版本中,数据类转换参数 field_descriptors 已重命名为 field_specifiers

    参考链接: #9067

postgresql

mysql

  • [mysql] [错误修复]

    恢复了 Inspector.has_table() 的行为,以报告 MySQL / MariaDB 的临时表。 这目前是所有其他包含的方言的行为,但由于不再使用 DESCRIBE 命令,因此在 1.4 中为 MySQL 删除了此行为; 此版本或任何先前版本中的 Inspector.has_table() 方法没有关于报告临时表的文档支持,因此先前的行为未定义。

    由于 SQLAlchemy 2.0 通过 Inspector.has_table() 添加了对临时表状态的正式支持,因此 MySQL / MariaDB 方言已恢复为像 SQLAlchemy 1.3 系列和以前一样使用 “DESCRIBE” 语句,并且添加了测试支持以将 MySQL / MariaDB 包含在此行为中。 1.4 试图改进的先前 ROLLBACK 发射问题在 SQLAlchemy 2.0 中不适用,因为 Connection 处理事务的方式得到了简化。

    DESCRIBE 是必要的,因为特别是 MariaDB 没有任何一致可用的公共信息模式,以便报告临时表,除了 DESCRIBE/SHOW COLUMNS,它们依赖于抛出错误来报告没有结果。

    参考链接: #9058

oracle

  • [oracle] [错误修复]

    支持外键约束的用例,其中本地列标记为 “invisible”。 当创建 ForeignKeyConstraint 时,通常会生成错误,该错误检查目标列是否在反射时被禁用,并且约束被跳过并发出警告,这与 Index 发生类似问题时已发生的方式相同。

    参考链接: #9059

2.0.0rc1

发布日期:2022 年 12 月 28 日

general

  • [general] [错误修复]

    修复了回归问题,其中基本 compat 模块调用 platform.architecture() 以检测某些系统属性,这导致对系统级 file 调用进行过度广泛的系统调用,在某些情况下(包括在某些安全环境配置中)无法使用该调用。

    此更改也已向后移植到:1.4.46

    参考链接: #8995

orm

  • [orm] [新特性]

    Mapper.eager_defaults 参数添加了一个新的默认值 “auto”,如果方言支持为正在运行的 INSERT 返回 RETURNING,以及 insertmanyvalues 可用,则该默认值将在工作单元刷新期间自动获取表默认值。 服务器端 UPDATE 默认值的预先获取(非常少见)继续仅在 Mapper.eager_defaults 设置为 True 时发生,因为 UPDATE 语句没有批量 RETURNING 形式。

    参考链接: #8889

  • [orm] [用例]

    在可扩展性方面对 Session 进行了调整,并更新了 ShardedSession 扩展

    参考链接: #7837

  • [orm] [用例]

    修订和改进了 “将外部事务加入会话” 的行为,从而可以显式控制 Session 将如何适应已具有事务且可能已建立保存点的传入 Connection。 新参数 Session.join_transaction_mode 包括一系列选项值,这些选项值可以通过多种方式适应现有事务,最重要的是允许 Session 完全以事务方式使用仅使用保存点的方式运行,同时在所有情况下都使外部启动的事务保持未提交和活动状态,从而允许测试套件回滚测试中发生的所有更改。

    此外,修订了 Session.close() 方法以完全关闭可能仍然存在的保存点,这也允许 “外部事务” 配方在 Session 未显式结束其自己的 SAVEPOINT 事务的情况下继续进行,而不会发出警告。

    参考链接: #9015

  • [orm] [用例]

    删除了在检测到非 Mapped[] 注解时,在声明性数据类映射类上使用 __allow_unmapped__ 属性的要求; 以前,会引发旨在支持旧版 ORM 类型映射的错误消息,此外,该消息没有提及专门与数据类一起使用的正确模式。 如果使用 registry.mapped_as_dataclass()MappedAsDataclass,则现在不再引发此错误消息。

    参考链接: #8973

  • [orm] [错误修复]

    修复了 UpdateDelete 等 DML 语句的内部 SQL 遍历中的问题,这些问题会导致其他潜在问题,尤其是在 ORM update/delete 功能中使用 lambda 语句的特定问题。

    此更改也已向后移植到:1.4.46

    参考链接: #9033

  • [orm] [错误修复]

    修复了 Session.merge() 未能保留使用 relationship.viewonly 参数指示的关系属性的当前加载内容的问题,从而破坏了使用 Session.merge() 从缓存和其他类似技术中拉取完全加载的对象策略。 在相关更改中,修复了将包含已加载但仍配置为映射上的 lazy='raise' 的关系的对象传递给 Session.merge() 时会失败的问题; 现在在合并过程中暂停对 “raise” 的检查,假设 Session.merge.load 参数保持其默认值 True

    总的来说,这是对 1.4 系列中从 #4994 开始引入的更改的行为调整,该更改将 “merge” 从默认应用于 “viewonly” 关系的级联集中删除。 由于 “viewonly” 关系在任何情况下都不会持久化,因此允许其内容在 “merge” 期间传输不会影响目标对象的持久化行为。 这允许 Session.merge() 正确地适应其用例之一,即将对象添加到 Session,这些对象在其他地方加载,通常是为了从缓存恢复。

    此更改也已向后移植到:1.4.45

    参考链接: #8862

  • [orm] [错误修复]

    修复了 with_expression() 中的问题,其中由从封闭 SELECT 引用的列组成的表达式在某些上下文中不会呈现正确的 SQL,在表达式具有与使用 query_expression() 的属性匹配的标签名称的情况下,即使 query_expression() 没有默认表达式。 目前,如果 query_expression() 确实具有默认表达式,则该标签名称仍用于该默认表达式,并且将继续忽略具有相同名称的附加标签。 总的来说,这种情况非常棘手,因此可能需要进一步调整。

    此更改也已向后移植到:1.4.45

    参考链接: #8881

  • [orm] [错误修复]

    如果 relationship() 中使用的 backref 名称命名了目标类上已分配了方法或属性的属性,则会发出警告,因为 backref 声明将替换该属性。

    参考链接: #4629

  • [orm] [错误修复]

    关于 Session.refresh() 的一系列更改和改进。 总体更改是,当要刷新关系绑定的属性时,对象的主键属性现在无条件地包含在刷新操作中,即使未过期,即使未在刷新中指定也是如此。

    • 改进了 Session.refresh(),以便在启用 autoflush(作为 Session 的默认设置)的情况下,autoflush 在刷新过程的早期部分发生,以便应用挂起的主键更改而不会引发错误。 以前,此 autoflush 在过程中发生得太晚,并且 SELECT 语句将不会使用正确的键来定位行,并且会引发 InvalidRequestError

    • 当存在上述条件时,即对象上存在未刷新的主键更改,但未启用 autoflush,则 refresh() 方法现在显式禁止操作继续进行,并且会引发信息性 InvalidRequestError,要求首先刷新挂起的主键更改。 以前,此用例只是被破坏了,并且无论如何都会引发 InvalidRequestError。 此限制是为了使主键属性可以安全地刷新,这对于能够使用关系绑定的辅助预加载器刷新对象的情况是必要的。 此规则适用于所有情况,以保持 API 行为的一致性,无论刷新中是否实际需要 PK 列,因为在任何情况下刷新对象上的某些属性而保持其他属性 “挂起” 都是不寻常的。

    • Session.refresh() 方法已得到增强,使得 relationship() 绑定并链接到预加载器的属性(在映射时或通过上次使用的加载器选项)将在所有情况下刷新,即使传递的属性列表不包含父行上的任何列也是如此。 这建立在作为 #1763 的一部分首次实现的非列属性功能之上,该功能在 1.4 中修复,允许预加载的关系绑定属性参与 Session.refresh() 操作。 如果刷新操作未指示要刷新父行上的任何列,则主键列仍将包含在刷新操作中,这允许加载像往常一样继续进入指示的辅助关系加载器。 以前,对于此条件,会引发 InvalidRequestError 错误 (#8703)

    • 修复了在 Session.refresh() 与过期属性以及诸如 selectinload() 之类的发出 “辅助” 查询的预加载器组合调用时,会发出不必要的附加 SELECT 的情况,如果主键属性也处于过期状态。 由于主键属性现在自动包含在刷新中,因此当关系加载器要去选择它们时,这些属性没有额外的加载 (#8997)

    • 修复了由 #8126 引起的回归问题,该问题在 2.0.0b1 中发布,其中如果传递了过期的列名称以及链接到 “辅助” 预加载器(例如 selectinload() 预加载器)的关系绑定属性的名称,则 Session.refresh() 方法将失败并显示 AttributeError 错误 (#8996)

    参考链接: #8703, #8996, #8997

  • [orm] [错误修复]

    改进了版本 1.4 中首次针对 #8456 所做的修复,该修复缩小了内部 “多态适配器” 的使用范围,这些适配器用于在使用 Mapper.with_polymorphic 参数时呈现 ORM 查询。 这些适配器非常复杂且容易出错,现在仅在显式用户提供的子查询用于 Mapper.with_polymorphic 的情况下使用,其中仅包括使用 polymorphic_union() 辅助函数的具体继承映射的用例,以及使用连接继承映射的别名子查询的旧用例,这在现代使用中是不需要的。

    对于使用内置多态加载方案的连接继承映射的最常见情况,包括那些使用 Mapper.polymorphic_load 参数设置为 inline 的情况,现在不再使用多态适配器。 这对查询的构建以及内部查询渲染过程的显著简化都具有积极的性能影响。

    针对的具体问题是允许 column_property() 在标量子查询中引用连接继承类,现在它的工作方式与直觉上可行的方式一样。

    参考链接: #8168

engine

  • [engine] [bug]

    修复了连接池中长期存在的竞争条件,该条件可能在 eventlet/gevent monkeypatching 方案中与 eventlet/gevent Timeout 条件结合使用时发生,其中由于超时而中断的连接池检出将无法清理失败状态,从而导致底层连接记录,有时甚至是数据库连接本身“泄漏”,使连接池处于无效状态,其中包含无法访问的条目。 此问题最初在 SQLAlchemy 1.2 中被识别和修复,用于 #4225,但是该修复中检测到的故障模式未能适应 BaseException,而不是 Exception,这阻止了 eventlet/gevent Timeout 被捕获。 此外,还识别出初始池连接中的一个块,并使用 BaseException -> “清理失败连接”块对其进行了强化,以适应此位置中的相同情况。 非常感谢 Github 用户 @niklaus 在识别和描述这个复杂问题上做出的不懈努力。

    此更改也已向后移植到:1.4.46

    参考链接: #8974

  • [engine] [bug]

    修复了 Result.freeze() 方法不适用于使用 text()Connection.exec_driver_sql() 的文本 SQL 的问题。

    此更改也已向后移植到:1.4.45

    参考链接: #8963

sql

  • [sql] [usecase]

    现在,当任何“字面绑定参数”渲染操作失败时,都会抛出一个信息丰富的重新引发,指示值本身和正在使用的数据类型,以帮助调试语句中正在渲染的字面参数。

    此更改也已向后移植到:1.4.45

    参考链接: #8800

  • [sql] [bug]

    修复了 lambda SQL 功能中的问题,其中字面值的计算类型不会考虑“与类型比较”的类型强制转换规则,从而导致 SQL 表达式(例如与 JSON 元素和类似元素进行比较)缺少类型信息。

    此更改也已向后移植到:1.4.46

    参考链接: #9029

  • [sql] [bug]

    修复了一系列关于渲染的绑定参数的位置,有时甚至是身份的问题,例如用于 SQLite、asyncpg、MySQL、Oracle 和其他数据库的参数。 一些编译形式无法正确维护参数的顺序,例如 PostgreSQL regexp_replace() 函数,CTE 构造的 “嵌套” 功能(首次在 #4123 中引入),以及通过使用 FunctionElement.column_valued() 方法与 Oracle 形成的 selectable 表。

    此更改也已向后移植到:1.4.45

    参考链接: #8827

  • [sql] [bug]

    添加了测试支持,以确保 SQLAlchemy 中所有 Compiler 实现中的所有编译器 visit_xyz() 方法都接受 **kw 参数,以便所有编译器在任何情况下都接受额外的关键字参数。

    参考链接: #8988

  • [sql] [bug]

    SQLCompiler.construct_params() 方法以及 SQLCompiler.params 访问器现在将返回与使用 render_postcompile 参数编译的编译语句完全对应的参数。 以前,该方法返回的参数结构本身与原始参数或扩展参数都不对应。

    现在不允许将新的参数字典传递给使用 render_postcompile 构建的 SQLCompilerSQLCompiler.construct_params(); 相反,为了为备用参数集创建新的 SQL 字符串和参数集,添加了一个新方法 SQLCompiler.construct_expanded_state(),它将为给定的参数集生成新的扩展形式,使用 ExpandedState 容器,该容器包括新的 SQL 语句和新的参数字典,以及位置参数元组。

    参考链接: #6114

  • [sql] [bug]

    为了适应第三方方言在绑定参数方面具有不同的字符转义需求,SQLAlchemy “转义”(即,在其位置替换为另一个字符)绑定参数名称中特殊字符的系统已为第三方方言进行了扩展,使用 SQLCompiler.bindname_escape_chars 字典,该字典可以在任何 SQLCompiler 子类上的类声明级别被覆盖。 作为此更改的一部分,还添加了点 "." 作为默认的“转义”字符。

    参考链接: #8994

typing

  • [typing] [bug]

    已为 sqlalchemy.ext.horizontal_shard 扩展以及 sqlalchemy.orm.events 模块完成了 pep-484 类型标注。 感谢 Gleb Kisenkov 的努力。

    参考链接: #6810, #9025

asyncio

  • [asyncio] [bug]

    AsyncResult 中删除了无功能的 merge() 方法。 此方法从未工作过,并且错误地包含在 AsyncResult 中。

    此更改也已向后移植到:1.4.45

    参考链接: #8952

postgresql

  • [postgresql] [bug]

    修复了 PostgreSQL Insert.on_conflict_do_update.constraint 参数接受 Index 对象,但不会将其扩展为单独的索引表达式,而是在 ON CONFLICT ON CONSTRAINT 子句中渲染其名称的错误,PostgreSQL 不接受这种方式; “约束名称”形式仅接受唯一约束或排除约束名称。 该参数继续接受索引,但现在将其扩展为其组件表达式以进行渲染。

    此更改也已向后移植到:1.4.46

    参考链接: #9023

  • [postgresql] [bug]

    调整了 PostgreSQL 方言在从表中反射列时考虑列类型的方式,以适应可能从 PG format_type() 函数返回 NULL 的备用后端。

    此更改也已向后移植到:1.4.45

    参考链接: #8748

  • [postgresql] [bug]

    添加了对 asyncpg 和 psycopg(仅限 SQLAlchemy 2.0)显式使用 PG 全文函数 的支持,关于第一个参数的 REGCONFIG 类型转换,之前会错误地转换为 VARCHAR,从而导致依赖显式类型转换的这些方言失败。 这包括对 to_tsvector, to_tsquery, plainto_tsquery, phraseto_tsquery, websearch_to_tsquery, ts_headline 的支持,它们中的每一个都将根据传递的参数数量来确定第一个字符串参数是否应解释为 PostgreSQL “REGCONFIG” 值; 如果是,则使用新添加的类型对象 REGCONFIG 对参数进行类型标注,然后在 SQL 表达式中显式转换。

    参考链接: #8977

  • [postgresql] [bug]

    修复了回归问题,其中新修订的 PostgreSQL 范围类型(例如 INT4RANGE)无法设置为 TypeDecorator 自定义类型的 impl,而是引发 TypeError

    参考链接: #9020

  • [postgresql] [bug]

    Range.__eq___() 现在在与不同类的实例进行比较时将返回 NotImplemented,而不是引发 AttributeError 异常。

    参考链接: #8984

sqlite

  • [sqlite] [usecase]

    添加了对 SQLite 后端反射外键构造上可能存在的 “DEFERRABLE” 和 “INITIALLY” 关键字的支持。 拉取请求由 Michael Gorven 提供。

    此更改也已向后移植到:1.4.45

    参考链接: #8903

  • [sqlite] [usecase]

    添加了对 SQLite 方言上的索引中包含的面向表达式的 WHERE 标准进行反射的支持,方式类似于 PostgreSQL 方言。 拉取请求由 Tobias Pfeiffer 提供。

    此更改也已向后移植到:1.4.45

    参考链接: #8804

oracle

  • [oracle] [bug]

    修复了 Oracle 编译器中 FunctionElement.column_valued() 的语法不正确的错误,渲染名称 COLUMN_VALUE 时未正确限定源表。

    此更改也已向后移植到:1.4.45

    参考链接: #8945

tests

  • [tests] [bug]

    修复了 tox.ini 文件中的问题,其中 tox 4.0 系列中对 “passenv” 格式的更改导致 tox 无法正常工作,特别是在 tox 4.0.6 及更高版本中引发错误。

    此更改也已向后移植到:1.4.46

  • [tests] [bug]

    为第三方方言添加了新的排除规则 unusual_column_name_characters,对于不支持列名中包含不寻常字符(例如点、斜杠或百分号)的第三方方言,即使名称被正确引用,也可以“关闭”该规则。

    此更改也已向后移植到:1.4.46

    参考链接: #9002

2.0.0b4

发布日期: 2022 年 12 月 5 日

orm

  • [orm] [feature]

    添加了一个新参数 mapped_column.use_existing_column,以适应单表继承映射的使用场景,该映射使用多个子类指示在超类上发生的同一列的模式。 以前可以通过使用 declared_attr() 结合在超类的 .__table__ 中定位现有列来实现此模式,但现在已更新为与 mapped_column() 以及 pep-484 类型标注一起使用,以一种简单而简洁的方式。

    参考链接: #8822

  • [orm] [usecase]

    添加了对扩展 Python enum.Enum 基类的自定义用户定义类型自动解析为 SQLAlchemy Enum SQL 类型的支持,当使用 Annotated Declarative Table 功能时。 该功能通过添加到 ORM 类型映射功能的新查找功能实现,并包括支持更改默认生成的 Enum 的参数,以及在映射中设置具有特定参数的特定 enum.Enum 类型。

    参考链接: #8859

  • [orm] [usecase]

    为相关的 ORM 属性构造(包括 mapped_column(), relationship() 等)添加了 mapped_column.compare 参数,以便在使用 Declarative Dataclass Mapping 功能时,为 Python dataclasses field() 提供 compare 参数。 拉取请求由 Simon Schiele 提供。

    参考链接: #8905

  • [orm] [bug]

    修复了在基于列的属性的 Mapped 注释中使用未知数据类型会静默地未能映射属性,而不是报告异常的问题; 现在会引发信息丰富的异常消息。

    参考链接: #8888

  • [orm] [bug]

    修复了一系列涉及 Mapped 与字典类型一起使用的问题,例如 Mapped[Dict[str, str] | None],在 Declarative ORM 映射中无法正确解释。 正确“取消可选化”此类型(包括在 type_annotation_map 中查找)的支持已得到修复。

    参考链接: #8777

  • [orm] [bug] [performance]

    ORM 启用 SQL 语句中的其他性能增强,特别是针对 ORM 语句构造中的 callcount,使用 aliased()union() 和类似的“复合”构造的组合,此外还直接改进了 corresponding_column() 内部方法的性能,该方法被 ORM 大量使用,例如 aliased() 和类似的构造。

    参考链接: #8796

  • [orm] [bug]

    修复了 Declarative Dataclass Mapping 功能中的错误,其中在映射中使用带有 __allow_unmapped__ 指令的普通 dataclass 字段将不会为这些字段创建具有正确类级别状态的 dataclass,在 dataclasses 本身已将 Field 对象替换为类级别默认值后,不适当地将原始 Field 对象复制到类。

    参考链接: #8880

  • [orm] [bug] [regression]

    修复了回归问题,其中刷新针对子查询映射的映射类(例如直接映射或某些形式的具体表继承)如果使用了 Mapper.eager_defaults 参数,则会失败。

    参考链接: #8812

  • [orm] [bug]

    修复了由 #8759 引起的 2.0.0b3 中的回归问题,其中使用限定名称(例如 sqlalchemy.orm.Mapped)指示 Mapped 名称将无法被 Declarative 识别为指示 Mapped 构造。

    参考链接: #8853

orm extensions

sql

  • [sql] [usecase]

    添加了 ScalarValues,可以用作列元素,允许在 IN 子句中或与 ANYALL 集合聚合结合使用 Values。 这个新类是使用方法 Values.scalar_values() 生成的。 当在 INNOT IN 操作中使用时,Values 实例现在被强制转换为 ScalarValues

    参考链接: #6289

  • [sql] [bug]

    修复了在缓存键生成中发现的关键内存问题,其中对于使用大量带有子查询的 ORM 别名的非常大型和复杂的 ORM 语句,缓存键生成可能会产生过大的键,其大小比语句本身大几个数量级。 非常感谢 Rollo Konig Brock 在最终确定此问题方面提供的非常有耐心和长期的帮助。

    此更改也 向后移植 到: 1.4.44

    参考链接: #8790

  • [sql] [bug]

    已重写 numeric pep-249 paramstyle 的方法,现在已完全支持,包括 “expanding IN” 和 “insertmanyvalues” 等功能。 参数名称也可能在源 SQL 构造中重复,这将使用单个参数在数字格式中正确表示。 引入了额外的数字 paramstyle,称为 numeric_dollar,这正是 asyncpg 方言使用的; paramstyle 等同于 numeric,只是数字指示符由美元符号而不是冒号指示。 asyncpg 方言现在直接使用 numeric_dollar paramstyle,而不是首先编译为 format 样式。

    numericnumeric_dollar paramstyle 假定目标后端能够以任何顺序接收数字参数,并将根据其位置(从 1 开始)与数字指示符的匹配,将给定的参数值与语句匹配。 这是 “numeric” paramstyle 的正常行为,尽管观察到 SQLite DBAPI 实现了未使用的 “numeric” 样式,该样式不遵循参数排序。

    参考链接: #8849

  • [sql] [bug]

    调整了 RETURNING 的渲染,特别是在使用 Insert 时,使其现在使用与 Select 构造相同的逻辑来生成标签来渲染列,这将包括消除歧义的标签,以及围绕命名列的 SQL 函数将使用列名本身进行标记。 这在从 Select 构造或从使用 UpdateBase.returning() 的 DML 语句中选择行时,建立了更好的交叉兼容性。 1.4 系列也进行了一个范围较小的更改,仅调整了函数标签问题。

    参考链接: #8770

schema

typing

  • [typing] [usecase]

    添加了一个新的类型 SQLColumnExpression,可以在用户代码中指示它来表示任何面向 SQL 列的表达式,包括基于 ColumnElement 的表达式以及基于 ORM QueryableAttribute 的表达式。此类型是一个真实的类,而不是别名,因此也可以用作其他对象的基础。还包括一个额外的 ORM 特定子类 SQLORMExpression

    参考: #8847

  • [typing] [bug]

    调整了 Python enum.IntFlag 类的内部使用,该类在 Python 3.11 中更改了其行为约定。这没有导致运行时故障,但是导致类型检查在 Python 3.11 下失败。

    参考: #8783

  • [typing] [bug]

    sqlalchemy.ext.mutable 扩展和 sqlalchemy.ext.automap 扩展现在已完全进行 pep-484 类型标注。非常感谢 Gleb Kisenkov 在这方面所做的努力。

    参考: #6810, #8667

  • [typing] [bug]

    修正了 relationship.secondary 参数的类型支持,该参数也可以接受返回 FromClause 的可调用对象(lambda)。

  • [typing] [bug]

    改进了 sessionmakerasync_sessionmaker 的类型标注,以便它们的返回值的默认类型将是 SessionAsyncSession,而无需显式地进行类型标注。以前,Mypy 不会自动从其泛型基类推断这些返回类型。

    作为此更改的一部分,SessionAsyncSessionsessionmakerasync_sessionmaker 的参数(超出初始的 “bind” 参数)已被设为仅关键字参数,其中包括一直以来都记录为关键字参数的参数,例如 Session.autoflushSession.class_ 等。

    感谢 Sam Bull 提供 Pull request。

    参考: #8842

  • [typing] [bug]

    修复了将返回列元素迭代器的可调用函数传递给 relationship.order_by 时,类型检查器会将其标记为错误的问题。

    参考: #8776

postgresql

  • [postgresql] [usecase]

    为了补充 #8690,新的比较方法,例如 Range.adjacent_to()Range.difference()Range.union() 等,已添加到 PG 特定的 range 对象中,使它们与底层 AbstractRange.comparator_factory 实现的标准运算符保持一致。

    此外,已更正该类的 __bool__() 方法,使其与常见的 Python 容器行为以及其他流行的 PostgreSQL 驱动程序的行为保持一致:它现在指示 range 实例是否空,而不是相反。

    感谢 Lele Gaifax 提供 Pull request。

    参考: #8765

  • [postgresql] [change] [asyncpg]

    将 asyncpg 使用的 paramstyle 从 format 更改为 numeric_dollar。这有两个主要好处,因为它不需要对语句进行额外的处理,并允许语句中存在重复的参数。

    参考: #8926

  • [postgresql] [bug] [mssql]

    仅对于 PostgreSQL 和 SQL Server 方言,调整了编译器,以便在 RETURNING 子句中渲染列表达式时,为生成标签的 SQL 表达式元素建议使用 SELECT 语句中使用的 “非匿名” 标签;主要示例是可能作为列类型一部分发出的 SQL 函数,其中标签名称默认应与列名称匹配。这恢复了版本 1.4.21 中由于 #6718, #6710 而更改的未明确定义的行为。Oracle 方言具有不同的 RETURNING 实现,并且未受此问题影响。版本 2.0 具有针对其广泛扩展的对其他后端 RETURNING 支持的全面更改。

    此更改也 向后移植 到: 1.4.44

    参考链接: #8770

  • [postgresql] [bug]

    为新的 PostgreSQL Range 类型添加了额外的类型检测,其中先前允许 psycopg2-native range 对象直接被 DBAPI 接收而无需 SQLAlchemy 拦截的情况停止工作,因为我们现在有自己的值对象。Range 对象已得到增强,使得 SQLAlchemy Core 在其他模糊情况(例如与日期的比较)中检测到它,并应用适当的绑定处理程序。感谢 Lele Gaifax 提供 Pull request。

    参考: #8884

mssql

  • [mssql] [bug]

    修复了由 #8177 引起的回归,重新启用 SQL server 的 setinputsizes,除非 fast_executemany + DBAPI executemany 用于语句,以及 #6047,实现 “insertmanyvalues”,它绕过 DBAPI executemany 以使用自定义 DBAPI execute 来处理 INSERT 语句。如果 fast_executemany 开启,则对于使用 “insertmanyvalues” 的多参数集 INSERT 语句,setinputsizes 将被错误地禁用,因为检查会错误地假设这是一个 DBAPI executemany 调用。“回归” 随后将是 “insertmanyvalues” 语句格式显然对不为每行使用相同类型的多行更敏感,因此在这种情况下尤其需要 setinputsizes。

    该修复程序修复了 fast_executemany 检查,以便仅在要使用真正的 DBAPI executemany 时才禁用 setinputsizes。

    参考: #8917

oracle

  • [oracle] [bug]

    继续修复 1.4.43 中发布的 Oracle 修复程序 #8708,其中以 Oracle 不允许的下划线开头的绑定参数名称在所有情况下仍然没有被正确转义。

    此更改也已向后移植到:1.4.45

    参考: #8708

tests

  • [tests] [bug]

    修复了测试套件的 --disable-asyncio 参数无法实际不运行 greenlet 测试的问题,并且也无法阻止套件为整个套件使用 “wrapping” greenlet。此参数现在确保在设置时,整个运行过程中都不会发生 greenlet 或 asyncio 的使用。

    此更改也 向后移植 到: 1.4.44

    参考: #8793

2.0.0b3

发布日期:2022 年 11 月 4 日

orm

  • [orm] [bug]

    修复了连接 eager loading 中的问题,在跨越三个 mapper 进行 eager loading 时,当中间 mapper 是继承的子类 mapper 时,特定的 outer/inner 连接 eager loads 组合会导致断言失败。

    此更改也向后移植到:1.4.43

    参考: #8738

  • [orm] [bug]

    修复了涉及 Select 构造的错误,其中 Select.select_from()Select.join() 的组合,以及使用 Select.join_from() 时,在查询的 columns 子句未显式包含 JOIN 的左侧实体的情况下,会导致 with_loader_criteria() 功能以及单表继承查询所需的 IN 标准无法渲染。现在,正确的实体已传输到内部生成的 Join 对象,以便正确添加针对左侧实体的标准。

    此更改也向后移植到:1.4.43

    参考: #8721

  • [orm] [bug]

    现在,当 with_loader_criteria() 选项用作添加到特定 “加载器路径” 的加载器选项时(例如在 Load.options() 中使用时),会引发信息丰富的异常。此用法不受支持,因为 with_loader_criteria() 仅旨在用作顶级加载器选项。以前,会生成内部错误。

    此更改也向后移植到:1.4.43

    参考: #8711

  • [orm] [bug]

    改进了 Session.get() 的 “字典模式”,以便可以在命名字典中指示引用主键属性名称的同义词名称。

    此更改也向后移植到:1.4.43

    参考: #8753

  • [orm] [bug]

    修复了继承 mapper 的 “selectin_polymorphic” 加载在 Mapper.polymorphic_on 参数引用未直接映射在类上的 SQL 表达式时无法正常工作的问题。

    此更改也向后移植到:1.4.43

    参考: #8704

  • [orm] [bug]

    修复了在使用 Query 对象作为迭代器时,如果在迭代过程中引发了用户定义的异常情况,则不会关闭底层 DBAPI cursor 的问题,从而导致迭代器被 Python 解释器关闭。当使用 Query.yield_per() 创建服务器端 cursor 时,这将导致通常与服务器端 cursor 不同步的 MySQL 相关问题,并且在没有直接访问 Result 对象的情况下,最终用户代码无法访问 cursor 以将其关闭。

    为了解决此问题,在迭代器方法中应用了 GeneratorExit 的捕获,这将在迭代器被中断的情况下关闭结果对象,并且根据定义,迭代器将由 Python 解释器关闭。

    作为为 1.4 系列实施的此更改的一部分,确保 Result 的所有实现(包括 ScalarResultMappingResult)上都提供了 .close() 方法。版本 2.0 的此更改还包括用于 Result 类的新上下文管理器模式。

    此更改也向后移植到:1.4.43

    参考: #8710

orm declarative

  • [orm] [declarative] [bug]

    在 ORM declarative 注解中添加了对为 relationship() 指定的类名以及 Mapped 符号本身的名称与它们的直接类名不同的支持,以支持诸如 Mapped 作为 from sqlalchemy.orm import Mapped as M 导入,或者相关的类名以类似的方式以备用名称导入的场景。此外,作为 relationship() 的前导参数给出的目标类名将始终取代左侧注解中给出的名称,以便在注解中仍然可以使用其他无法导入且也不与类名匹配的名称。

    参考: #8759

  • [orm] [declarative] [bug]

    改进了对使用不包含 Mapped[] 的注解的旧版 1.4 映射的支持,通过确保可以使用 __allow_unmapped__ 属性来允许此类旧版注解通过 Annotated Declarative 而不会引发错误,并且不会在 ORM 运行时上下文中进行解释。此外,改进了检测到这种情况时生成的错误消息,并为应如何处理这种情况添加了更多文档。遗憾的是,当前的架构无法在运行时通过 1.4 WARN_SQLALCHEMY_20 迁移警告来检测到此特定的配置问题。

    参考: #8692

  • [orm] [declarative] [bug]

    更改了 Mapper 的基本配置行为,其中直接或封闭在 mapper 属性对象中的 Mapper.properties 字典中显式存在的 Column 对象,现在将按照它们在映射的 Table (或其他 selectable)本身中出现的顺序进行映射(假设它们实际上是该表的列列表的一部分),从而在映射的 selectable 中保持与映射类上工具化的列相同的顺序,以及在该 mapper 的 ORM SELECT 语句中呈现的内容。以前(“以前” 指的是自 0.0.1 版本以来),Mapper.properties 字典中的 Column 对象将始终首先映射,在映射的 Table 中的其他列映射之前,导致 mapper 向映射类分配属性的顺序以及它们在语句中呈现的顺序出现差异。

    此更改最显著地发生在 Declarative 将声明的列分配给 Mapper 的方式中,特别是当 Column(或 mapped_column())对象的 DDL 名称与映射的属性名称显式不同时,以及当使用诸如 deferred() 等构造时。新的行为将使映射的 Table 中的列顺序与属性映射到类上的顺序相同,在 Mapper 本身中分配,并在 ORM 语句(例如 SELECT 语句)中呈现,而与 Column 如何针对 Mapper 配置无关。

    参考: #8705

  • [orm] [declarative] [bug]

    修复了新的 dataclass 映射功能中的问题,在某些情况下,在 decalrative base / abstract base / mixin 上声明的列会泄漏到继承子类的构造函数中。

    参考: #8718

  • [bug] [orm declarative]

    修复了 declarative 类型解析器(即解析 ForwardRef 对象)中的问题,其中在一个特定源文件中为列声明的类型在最终映射的类位于另一个源文件时会引发 NameError。现在,这些类型是根据使用类型的每个类的模块来解析的。

    参考: #8742

engine

  • [engine] [feature]

    为了更好地支持迭代 ResultAsyncResult 对象的使用场景,其中用户定义的异常可能会中断迭代,这两个对象以及诸如 ScalarResult, MappingResult, AsyncScalarResult, AsyncMappingResult 等变体现在都支持上下文管理器用法,其中结果将在上下文管理器块的末尾关闭。

    此外,确保上述所有 Result 对象都包含 Result.close() 方法以及 Result.closed 访问器,包括以前没有 .close() 方法的 ScalarResultMappingResult

    参考: #8710

  • [engine] [usecase]

    添加了新的参数 PoolEvents.reset.reset_state 参数到 PoolEvents.reset() 事件中,并加入了弃用逻辑,该逻辑将继续接受使用先前参数集的事件钩子。这表明了关于重置如何发生的各种状态信息,并用于允许自定义重置方案在给定的完整上下文中进行。

    在此更改中,包含了一个也向后移植到 1.4 的修复,该修复重新启用了 PoolEvents.reset() 事件,使其在所有情况下继续发生,包括当 Connection 已经“重置”连接时。

    这两个更改共同允许使用 PoolEvents.reset() 事件来实现自定义重置方案,而不是使用 PoolEvents.checkin() 事件(该事件继续像往常一样运行)。

    参考链接: #8717

  • [engine] [bug] [回归]

    修复了当 PoolEvents.reset() 事件钩子在 Connection 关闭并正在将其 DBAPI 连接返回连接池的过程中,并非在所有情况下都会被调用的问题。

    场景是当 Connection 已经在将其 DBAPI 连接返回池的过程中对其发出了 .rollback() 时,它将指示连接池放弃执行其自身的“重置”以节省额外的函数调用。然而,这阻止了自定义池重置方案在此钩子中使用,因为此类钩子按定义执行的操作不仅仅是调用 .rollback(),并且需要在所有情况下都被调用。这是版本 1.4 中出现的回归。

    对于版本 1.4,PoolEvents.checkin() 仍然是可行的替代事件钩子,可用于自定义“重置”实现。版本 2.0 将提供改进版的 PoolEvents.reset(),它会在更多场景中被调用,例如终止 asyncio 连接,并且还会传递关于重置的上下文信息,以允许“自定义连接重置”方案能够以不同的方式响应不同的重置场景。

    此更改也向后移植到:1.4.43

    参考链接: #8717

sql

  • [sql] [bug]

    修复了当 literal_column() 构造在 Select 构造以及其他可能生成“匿名标签”的地方(如果字面表达式包含可能干扰格式字符串的字符,例如左括号)的上下文中无法正常工作的问题,这是由于“匿名标签”结构的实现细节导致的。

    此更改也向后移植到:1.4.43

    参考链接: #8724

typing

  • [typing] [bug]

    修正了 engine 和 async engine 包中的各种类型问题。

postgresql

mssql

  • [mssql] [bug]

    修复了 Inspector.has_table() 的问题,当用于 SQL Server 方言的临时表时,由于某些 Azure 变体上不支持的不必要的信息模式查询,会导致在这些服务器版本上失败。此拉取请求由 Mike Barry 友情提供。

    此更改也向后移植到:1.4.43

    参考链接: #8714

  • [mssql] [bug] [reflection]

    修复了 Inspector.has_table() 的问题,当用于 SQL Server 方言的视图时,由于 1.4 系列中的回归(该回归移除了对 SQL Server 上此功能的支持),会错误地返回 False。此问题在 2.0 系列中不存在,因为 2.0 系列使用了不同的反射架构。添加了测试支持以确保 has_table() 保持按照关于视图的规范工作。

    此更改也向后移植到:1.4.43

    参考链接: #8700

oracle

  • [oracle] [bug]

    修复了绑定参数名称(包括那些从类似名称的数据库列自动派生的名称)包含通常需要在 Oracle 中使用引号引起来的字符时,在使用 Oracle 方言的“扩展参数”时不会被转义,从而导致执行错误的问题。Oracle 方言用于绑定参数的常用“引号”不适用于“扩展参数”架构,因此现在使用针对 Oracle 特定的字符/转义列表来代替对大量字符进行转义。

    此更改也向后移植到:1.4.43

    参考: #8708

  • [oracle] [bug]

    修复了为了获取默认小数点字符而在首次连接时查询的 nls_session_parameters 视图可能不可用(取决于 Oracle 连接模式),因此会引发错误的问题。检测小数字符的方法已简化为直接测试小数值,而不是读取系统视图,这在任何后端/驱动程序上都有效。

    此更改也向后移植到:1.4.43

    参考链接: #8744

2.0.0b2

发布日期: 2022 年 10 月 20 日

orm

  • [orm] [bug]

    移除了在使用 ORM 启用的 update/delete 时,关于按名称评估列而发出的警告,该警告最初在 #4073 中添加;此警告实际上掩盖了一种场景,否则可能会根据实际列为 ORM 映射属性填充错误的 Python 值,因此移除了此已弃用的情况。在 2.0 中,ORM 启用的 update/delete 使用 “auto” 作为 “synchronize_session”,这应该为任何给定的 UPDATE 表达式自动执行正确的操作。

    参考链接: #8656

orm declarative

  • [orm] [declarative] [usecase]

    添加了对也是 Generic 子类的映射类的支持,可以在语句和对 inspect() 的调用中将其指定为 GenericAlias 对象(例如 MyClass[str])。

    参考链接: #8665

  • [orm] [declarative] [bug]

    改进了 DeclarativeBase 类,使其在与其他 mixin(如 MappedAsDataclass)组合使用时,类的顺序可以是任意顺序。

    参考链接: #8665

  • [orm] [declarative] [bug]

    修复了新的 ORM 类型化声明式映射中的错误,其中在多对一关系的类型注解中使用 Optional[MyClass] 或类似形式(如 MyClass | None)的功能未实现,导致错误。文档中还为关系配置文档添加了此用例的说明。

    参考链接: #8668

  • [orm] [declarative] [bug]

    修复了新的 dataclass 映射功能中的问题,其中传递给 dataclasses API 的参数在处理覆盖 mapped_column() 声明的 mixin 时,有时会错误排序,从而导致初始化程序问题。

    参考链接: #8688

sql

  • [sql] [bug] [回归]

    修复了新的 “insertmanyvalues” 功能中的错误,其中包含带有 bindparam() 的子查询的 INSERT 语句在 “insertmanyvalues” 格式中无法正确呈现。这直接影响了 psycopg2,因为 “insertmanyvalues” 无条件地与此驱动程序一起使用。

    参考链接: #8639

typing

  • [typing] [bug]

    修复了当使用方法定义 __tablename____mapper_args____table_args__ 时,pylance 严格模式会报告 “实例变量覆盖类变量” 的类型问题。

    参考链接: #8645

  • [typing] [bug]

    修复了 pylance 严格模式会为 mapped_column() 构造报告 “部分未知” 数据类型的类型问题。

    参考链接: #8644

mssql

  • [mssql] [bug]

    修复了由 SQL Server pyodbc 更改 #8177 引起的回归,我们现在默认使用 setinputsizes();对于 VARCHAR,如果字符大小大于 4000 个字符(或 2000 个字符,具体取决于数据),则会失败,因为传入的数据类型是 NVARCHAR,其限制为 4000 个字符,尽管 VARCHAR 可以处理无限字符。当数据类型的大小 > 2000 个字符时,现在将额外的 pyodbc 特定类型信息传递给 setinputsizes()。此更改也应用于 JSON 类型,该类型也受到大型 JSON 序列化问题的影响。

    参考链接: #8661

  • [mssql] [bug]

    Sequence 构造恢复到 1.4 系列之前的 DDL 行为,其中创建没有附加参数的 Sequence 将发出简单的 CREATE SEQUENCE 指令,不带任何额外的 “起始值” 参数。对于大多数后端,无论如何,这都是以前的工作方式;但是,对于 MS SQL Server,此数据库上的默认值为 -2**63;为了防止此通常不切实际的默认值在 SQL Server 上生效,应提供 Sequence.start 参数。由于 Sequence 的使用对于 SQL Server 来说是不寻常的,SQL Server 多年来已将 IDENTITY 标准化,因此希望此更改的影响最小。

    参考链接: #7211

2.0.0b1

发布日期: 2022 年 10 月 13 日

general

  • [general] [changed]

    迁移了代码库以移除所有先前标记为在 2.0 中移除的 2.0 之前的行为和架构,包括但不限于:

    • 移除所有 Python 2 代码,最低版本现在是 Python 3.7

    • EngineConnection 现在使用新的 2.0 风格的工作方式,其中包括 “autobegin”、库级别的自动提交已移除、子事务和 “分支” 连接已移除

    • 结果对象使用 2.0 风格的行为;Row 完全是一个命名的元组,没有 “mapping” 行为,使用 RowMapping 获取 “mapping” 行为

    • 所有 Unicode 编码/解码架构已从 SQLAlchemy 中移除。由于 Python 3,所有现代 DBAPI 实现都透明地支持 Unicode,因此 convert_unicode 功能以及在 DBAPI cursor.description 等中查找字节串的相关机制已被移除。

    • 来自 MetaDataTable 以及所有先前可以引用 “绑定引擎” 的 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 参数现在必须保持其新的默认值 Falsesave-update 级联不再沿反向引用级联。

    • Session.future 参数必须始终设置为 TrueSession 的 2.0 风格的事务模式现在始终生效。

    • 加载器选项不再接受属性名称的字符串。长期记录的使用 Class.attrname 作为加载器选项目标的方法现在是标准方法。

    • 移除了 select() 的旧式形式,包括 select([cols])some_table.select() 的 “whereclause” 和关键字参数。

    • 移除了 Select 上的旧式 “原地修改器” 方法,例如 append_whereclause()append_order_by() 等。

    • 移除了非常旧的 “dbapi_proxy” 模块,该模块在非常早期的 SQLAlchemy 版本中用于在原始 DBAPI 连接上提供透明的连接池。

    参考链接: #7257

  • [general] [changed]

    Query.instances() 方法已被弃用。此方法的行为约定(即它可以迭代通过任意结果集的对象)早已过时且不再测试。任意语句可以使用诸如 :meth`.Select.from_statement` 或 aliased() 之类的构造返回对象。

platform

  • [platform] [feature]

    SQLAlchemy C 扩展已被替换为用 Cython 编写的全新实现。与之前的 C 扩展一样,pypi 上提供了适用于各种平台的预构建 wheel 文件,因此对于常用平台来说,构建不是问题。对于自定义构建,python setup.py build_ext 像以前一样工作,只需要额外安装 Cython。pyproject.toml 现在也是源代码的一部分,它将在使用 pip 时建立正确的构建依赖项。

    参考链接: #7256

  • [platform] [change]

    SQLAlchemy 的源代码构建和安装现在包含一个 pyproject.toml 文件,以实现完全的 PEP 517 支持。

    参考链接: #7311

orm

  • [orm] [feature] [sql]

    为所有包含的方言添加了名为 “insertmanyvalues” 的新功能,这些方言支持 RETURNING。这是在 ORM 批量插入与 psycopg2 现在在大多数情况下使用 RETURNING 批量处理语句 中首次为 psycopg2 驱动程序引入的 “快速 executemany” 功能的概括,它允许 ORM 将 INSERT 语句批量处理成更高效的 SQL 结构,同时仍然能够使用 RETURNING 获取新生成的主键和 SQL 默认值。

    此功能现在适用于许多支持 RETURNING 以及 INSERT 的多个 VALUES 构造的方言,包括所有 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.keyAttributeEvents.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]

    现在,composite() 映射构造在使用 Python dataclass 时支持自动解析值;不再需要实现 __composite_values__() 方法,因为此方法是从 dataclass 的检查中派生出来的。

    此外,由 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] [feature]

    使用包含 ForeignKey 引用的 Column 对象的声明性 mixin 不再需要使用 declared_attr() 来实现此映射;当列应用于声明性映射时,ForeignKey 对象会与 Column 本身一起复制。

  • [orm] [usecase]

    load_only() 加载器选项添加了 load_only.raiseload 参数,以便未加载的属性可以具有“raise”行为而不是延迟加载。以前,实际上没有办法直接使用 load_only() 选项来做到这一点。

  • [orm] [change]

    为了更好地适应显式类型,一些通常在内部构造的 ORM 构造的名称已更改为更简洁的名称,这些名称也与其构造函数的名称匹配(大小写不同),以便在消息传递以及类型提示中更易读,在所有情况下,都为旧名称保留别名,以在可预见的未来保持兼容性。

  • [orm] [change]

    为了与突出的 ORM 概念 Mapped 保持一致,面向字典的集合的名称 attribute_mapped_collection()column_mapped_collection()MappedCollection 已更改为 attribute_keyed_dict()column_keyed_dict()KeyFuncDict,使用短语 “dict” 以最大程度地减少与术语 “mapped” 混淆。旧名称将无限期保留,没有计划删除。

    参考资料: #8608

  • [orm] [bug]

    如果 Result 对象在硬关闭后使用,包括在调用 “single row or value” 方法(如 Result.first()Result.scalar())后发生的 “hard close”,则所有 Result 对象现在将始终如一地引发 ResourceClosedError。这已经是为 Core 语句执行返回的最常见的结果对象类别的行为,即基于 CursorResult 的结果对象,因此这种行为并非新行为。但是,此更改已扩展到正确适应在使用 2.0 样式 ORM 查询时返回的 ORM “过滤” 结果对象,这些对象以前会以返回空结果的 “soft closed” 样式运行,或者根本不会真正 “soft close”,并且会继续从底层游标生成结果。

    作为此更改的一部分,还向基本 Result 类添加了 Result.close(),并为 ORM 使用的过滤结果实现实现了它,以便在使用 yield_per 执行选项时,可以调用底层 CursorResult 上的 CursorResult.close() 方法,以便在获取剩余 ORM 结果之前关闭服务器端游标。这再次适用于 Core 结果集,但此更改也使其可用于 2.0 样式 ORM 结果。

    此更改也 向后移植 到: 1.4.27

    参考资料: #7274

  • [orm] [bug]

    修复了 registry.map_declaratively() 方法返回内部 “mapper config” 对象,而不是 API 文档中声明的 Mapper 对象的问题。

  • [orm] [bug]

    修复了至少在 1.3 版本(如果不是更早版本,在 1.0 之后)中出现的性能回归问题,其中加载延迟列(那些显式使用 defer() 映射的列,而不是来自连接继承子类的已过期非延迟列)不会使用 “优化” 查询(仅查询包含未加载列的直接表),而是运行完整的 ORM 查询,这将为所有基表发出 JOIN,这在仅加载子类中的列时是不必要的。

    参考资料: #7463

  • [orm] [bug]

    主要重写了 Load 对象和相关加载器策略模式的内部结构,以利用现在仅支持属性绑定路径而不是字符串这一事实。重写希望使解决加载器策略系统中的新用例和细微问题更加直接。

    参考资料: #6986

  • [orm] [bug]

    对 “deferred” / “load_only” 策略选项集进行了一项改进,其中如果从一个查询中的两个不同逻辑路径加载某个对象,则已通过至少一个选项配置为填充的属性将在所有情况下填充,即使同一对象的其他加载路径未设置此选项也是如此。以前,这取决于哪个 “路径” 首先寻址到对象,具有一定的随机性。

    参考资料: #8166

  • [orm] [bug]

    修复了在针对连接继承子类创建语句的 ORM 启用 UPDATE 中的问题,仅更新本地表列,其中 “fetch” 同步策略不会为使用 RETURNING 进行 fetch 同步的数据库呈现正确的 RETURNING 子句。还调整了 UPDATE FROM 和 DELETE FROM 语句中 RETURNING 使用的策略。

    参考资料: #8344

  • [orm] [bug] [asyncio]

    beginbegin_nested 中删除了未使用的 **kw 参数。这些 kw 未被使用,并且似乎是错误地添加到 API 中的。

    参考资料: #7703

  • [orm] [bug]

    更改了 attribute_mapped_collection()column_mapped_collection()(现在称为 attribute_keyed_dict()column_keyed_dict())在填充字典时使用的属性访问方法,以断言要用作字典键的对象上的数据值实际上存在,而不是由于属性从未实际分配而使用 “None”。这用于防止在通过 backref 分配时错误地为键错误填充 None,其中对象上的 “key” 属性尚未分配。

    由于这里的故障模式是一种短暂的情况,通常不会持久保存到数据库,并且很容易通过基于参数分配顺序的类的构造函数生成,因此很可能许多应用程序已经包含此行为,但被静默跳过。为了适应现在引发此错误的应用程序,还为 attribute_keyed_dict()column_keyed_dict() 添加了一个新参数 attribute_keyed_dict.ignore_unpopulated_attribute,该参数导致跳过错误的 backref 分配。

    参考资料: #8372

  • [orm] [bug]

    AbstractConcreteBase 声明性 mixin 类添加了新参数 AbstractConcreteBase.strict_attrs。此参数的效果是子类上的属性范围被正确地限制为声明每个属性的子类,而不是以前的行为,即整个层次结构的所有属性都应用于基本 “抽象” 类。这产生了更清晰、更正确的映射,其中子类不再具有仅与同级类相关的无用属性。此参数的默认值为 False,这使以前的行为保持不变;这是为了支持现有代码,这些代码显式地在查询中使用这些属性。要迁移到较新的方法,请根据需要将显式属性应用于抽象基类。

    参考资料: #8403

  • [orm] [bug]

    修订了关于主键和 “多态鉴别器” 列的 defer() 的行为,以便这些列不再可延迟,无论是显式地还是在使用通配符(例如 defer('*'))时。以前,通配符延迟不会加载 PK/多态列,这在所有情况下都会导致错误,因为 ORM 依赖于这些列来生成对象标识。显式延迟主键列的行为保持不变,因为这些延迟已经被隐式忽略。

    参考资料: #7495

  • [orm] [bug]

    修复了 Mapper.eager_defaults 参数行为中的错误,以便仅在表定义中的客户端 SQL default 或 onupdate 表达式将触发在使用 RETURNING 或 SELECT 的 fetch 操作,当 ORM 为行发出 INSERT 或 UPDATE 时。以前,只有作为表 DDL 和/或服务器端 onupdate 表达式一部分建立的服务器端默认值才会触发此 fetch,即使在呈现 fetch 时会包含客户端 SQL 表达式。

    参考资料: #7438

engine

  • [engine] [feature]

    现在,DialectEvents.handle_error() 事件已从 EngineEvents 套件移动到 DialectEvents 套件,现在参与连接池 “pre ping” 事件,适用于那些使用断开连接代码来检测数据库是否处于活动状态的方言。这允许最终用户代码更改 “pre ping” 的状态。请注意,这不包括包含本机 “ping” 方法的方言,例如 psycopg2 或大多数 MySQL 方言。

    参考文献: #5648

  • [engine] [feature]

    ConnectionEvents.set_connection_execution_options()ConnectionEvents.set_engine_execution_options() 事件钩子现在允许就地修改给定的选项字典,其中新内容将作为要执行的最终执行选项接收。以前,不支持就地修改字典。

  • [engine] [usecase]

    create_engine.isolation_level 参数推广到基本方言,使其不再依赖于各个方言的存在。此参数设置 “隔离级别” 设置,以便在连接池创建所有新数据库连接后立即发生,其中该值随后保持设置状态,而不会在每次检入时重置。

    create_engine.isolation_level 参数在功能上基本上等同于通过 Engine.execution_options()Engine.execution_options.isolation_level 参数用于引擎范围的设置。不同之处在于,前一个设置仅在创建连接时分配一次隔离级别,而后一个设置在每次连接检出时设置和重置给定的级别。

    参考资料: #6342

  • [engine] [change]

    关于引擎和方言的一些小的 API 更改

    参考资料: #7122

  • [engine] [bug] [regression]

    修复了回归问题,其中 CursorResult.fetchmany() 方法在结果完全耗尽时,无法自动关闭服务器端游标(即,当 stream_resultsyield_per 正在使用时,无论是 Core 还是 ORM 导向的结果)。

    此更改也 向后移植 到: 1.4.27

    参考资料: #7274

  • [engine] [bug]

    修复了未来版本 Engine 中的一个问题,即当调用 Engine.begin() 并进入上下文管理器时,如果由于某些原因(例如事件处理程序引发异常)导致实际的 BEGIN 操作失败,则连接不会关闭;这个用例在引擎的未来版本中未能进行测试。请注意,在 Core 和 ORM 中处理 begin() 代码块的“未来”上下文管理器实际上直到上下文管理器真正进入时才运行 “BEGIN” 操作。这与预先运行 “BEGIN” 操作的旧版本不同。

    此更改也 向后移植 到: 1.4.27

    参考链接: #7272

  • [引擎] [错误修复]

    QueuePool 现在在 pool_size=0 时忽略 max_overflow,从而在所有情况下都正确地使连接池无限制。

    参考链接: #8523

  • [引擎] [错误修复]

    为了提高安全性,当调用 str(url) 时,URL 对象现在默认使用密码混淆。要使用明文密码字符串化 URL,可以使用 URL.render_as_string(),并将 URL.render_as_string.hide_password 参数设置为 False。感谢我们的贡献者为此拉取请求。

    参考链接: #8567

  • [引擎] [错误修复]

    Inspector.has_table() 方法现在将一致地检查给定名称的视图和表。以前,此行为依赖于方言,PostgreSQL、MySQL/MariaDB 和 SQLite 支持它,而 Oracle 和 SQL Server 不支持。第三方方言也应努力确保其 Inspector.has_table() 方法搜索给定名称的视图和表。

    参考链接: #7161

  • [引擎] [错误修复]

    修复了 Result.columns() 方法中的一个问题,即在某些情况下,特别是 ORM 结果对象的情况下,使用单个索引调用 Result.columns() 可能会导致 Result 生成标量对象而不是 Row 对象,就像调用了 Result.scalars() 方法一样。在 SQLAlchemy 1.4 中,这种情况会发出警告,表明该行为将在 SQLAlchemy 2.0 中更改。

    参考链接: #7953

  • [引擎] [错误修复]

    DefaultGenerator 对象(例如 Sequence)传递给 Connection.execute() 方法已被弃用,因为此方法的类型被定义为返回 CursorResult 对象,而不是纯标量值。应该使用 Connection.scalar() 方法,该方法已使用新的内部代码路径进行重新设计,以适合调用 SELECT 来获取默认生成对象,而无需通过 Connection.execute() 方法。

  • [引擎] [已移除]

    移除了先前已弃用的 case_sensitive 参数,该参数来自 create_engine(),它只会影响 Core-only 结果集行中字符串列名的查找;它对 ORM 的行为没有影响。case_sensitive 指向的有效行为仍保持其默认值 True,这意味着在 row._mapping 中查找的字符串名称将区分大小写匹配,就像任何其他 Python 映射一样。

    请注意,case_sensitive 参数与大小写敏感性控制、引用和 DDL 标识符名称的“名称规范化”(即,为认为所有大写单词都不区分大小写的数据库进行转换)的一般主题没有任何关系,后者仍然是 SQLAlchemy 的正常核心功能。

  • [引擎] [已移除]

    移除了遗留和已弃用的包 sqlalchemy.databases。请改用 sqlalchemy.dialects

    参考链接: #7258

  • [引擎] [弃用]

    create_engine() 函数中,create_engine.implicit_returning 参数已被弃用;该参数在 Table 对象上仍然可用。此参数最初旨在在 SQLAlchemy 首次开发时启用“隐式返回”功能,并且默认情况下未启用。在现代使用中,没有理由禁用此参数,并且已观察到它会引起混淆,因为它会降低性能,并使 ORM 更难检索最近插入的服务器默认值。该参数在 Table 上仍然可用,专门用于适应使 RETURNING 不可行的数据库级边缘情况,目前唯一的例子是 SQL Server 的限制,即 INSERT RETURNING 不能用于在其上具有 INSERT 触发器的表。

    参考链接: #6962

sql

  • [sql] [新功能]

    添加了长期以来一直要求的不区分大小写的字符串运算符 ColumnOperators.icontains(), ColumnOperators.istartswith(), ColumnOperators.iendswith(),它们生成不区分大小写的 LIKE 组合(在 PostgreSQL 上使用 ILIKE,在所有其他后端上使用 LOWER() 函数),以补充现有的 LIKE 组合运算符 ColumnOperators.contains(), ColumnOperators.startswith() 等。非常感谢 Matias Martinez Rebori 在实施这些新方法方面所做的细致而完整的工作。

    参考链接: #3482

  • [sql] [新功能]

    在所有 FromClause 对象上的 FromClause.c 集合中添加了新语法,允许将键的元组传递给 __getitem__(),以及对 select() 构造的支持,以直接处理生成的类似元组的集合,从而允许使用语法 select(table.c['a', 'b', 'c'])。返回的子集合本身也是一个 ColumnCollection,现在也可以被 select() 和类似函数直接使用。

    参考链接: #8285

  • [sql] [新功能]

    添加了新的后端无关的 Uuid 数据类型,它从 PostgreSQL 方言中推广而来,现在成为核心类型,并将 UUID 从 PostgreSQL 方言迁移过来。SQL Server UNIQUEIDENTIFIER 数据类型也成为处理 UUID 的数据类型。感谢 Trevor Gross 在这方面的帮助。

    参考链接: #7212

  • [sql] [新功能]

    Double, DOUBLE, DOUBLE_PRECISION 数据类型添加到基本 sqlalchemy. 模块命名空间,用于显式使用双精度/双精度以及通用“双精度”数据类型。使用 Double 以获得通用支持,它将根据不同后端的需求解析为 DOUBLE/DOUBLE PRECISION/FLOAT。

    参考链接: #5465

  • [sql] [用例]

    更改了 Insert 构造的编译机制,使得即使 “自增主键” 列值存在于参数集中或 Insert.values() 方法中作为普通绑定值,也会通过 cursor.lastrowid 或 RETURNING 获取,对于已知即使传递显式 NULL 也会生成自增值的特定后端上的单行 INSERT 语句。这恢复了 1.3 系列中的行为,适用于单独的参数集以及 Insert.values() 的用例。在 1.4 中,参数集行为意外地更改为不再执行此操作,但 Insert.values() 方法仍然会获取自增值,直到 1.4.21 版本,#6770 再次意外地更改了行为,因为此用例从未被覆盖。

    现在的行为被定义为 “工作正常”,以适应 SQLite、MySQL 和 MariaDB 等数据库会忽略显式 NULL 主键值,但仍然调用自增生成器的情况。

    参考链接: #7998

  • [sql] [用例]

    在使用 PostgreSQL、MySQL、MariaDB、MSSQL、Oracle 方言提供的 SQL 编译器以及 literal_binds 时,添加了修改后的 ISO-8601 渲染(即,将 ISO-8601 中的 T 转换为空格)。对于 Oracle,ISO 格式包装在适当的 TO_DATE() 函数调用中。以前,此渲染未针对特定于方言的编译实现。

    参考链接: #5052

  • [sql] [用例]

    HasCTE.add_cte() 添加了新参数 HasCTE.add_cte.nest_here,它将在父语句级别 “嵌套” 给定的 CTE。此参数等效于使用 HasCTE.cte.nesting 参数,但在某些情况下可能更直观,因为它允许同时设置嵌套属性和 CTE 的显式级别。

    HasCTE.add_cte() 方法也接受多个 CTE 对象。

    参考链接: #7759

  • [sql] [错误修复]

    当使用 Select.select_from() 方法时,在 select() 构造上建立的 FROM 子句现在将在渲染的 SELECT 的 FROM 子句中首先渲染,这有助于保持传递给 Select.select_from() 方法的子句的顺序,而不会受到查询的其他部分也提及这些子句的影响。如果 Select 的其他元素也生成 FROM 子句,例如 columns 子句或 WHERE 子句,则这些子句将在 Select.select_from() 传递的子句之后渲染,假设它们也没有显式传递给 Select.select_from()。此改进在某些情况下很有用,在这些情况下,特定的数据库基于 FROM 子句的特定顺序生成理想的查询计划,并允许完全控制 FROM 子句的顺序。

    参考链接: #7888

  • [sql] [错误修复]

    Enum.length 参数用于设置非原生枚举类型的 VARCHAR 列的长度,现在在为 VARCHAR 数据类型发出 DDL 时无条件使用,包括当 Enum.native_enum 参数对于继续使用 VARCHAR 的目标后端设置为 True 时。以前,在这种情况下,该参数会被错误地忽略。先前为此情况发出的警告现已移除。

    参考链接: #7791

  • [sql] [错误修复]

    对于 Python 整数的就地类型检测(例如表达式 literal(25)),现在也将应用基于值的适配,以适应 Python 大整数,其中确定的数据类型将是 BigInteger 而不是 Integer。这适用于 asyncpg 等方言,它们既向驱动程序发送隐式类型信息,又对数字比例敏感。

    参考链接: #7909

  • [sql] [错误修复]

    为所有 “Create” / “Drop” 构造添加了 if_existsif_not_exists 参数,包括 CreateSequence, DropSequence, CreateIndex, DropIndex 等,允许在 DDL 中渲染通用 “IF EXISTS” / “IF NOT EXISTS” 短语。拉取请求由 Jesse Bakker 提供。

    参考链接: #7354

  • [sql] [错误修复]

    改进了 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] [错误修复]

    使用 “/” 和 “//” 运算符实现了对 “truediv” 和 “floordiv” 的完全支持。现在,使用 Integer 在两个表达式之间进行的 “truediv” 运算会将结果视为 Numeric,并且方言级别的编译将在特定于方言的基础上将右操作数强制转换为数字类型,以确保实现 truediv。对于 floordiv,也为那些默认情况下尚不支持 floordiv 的数据库(MySQL,Oracle)添加了转换,在这种情况下会渲染 FLOOR() 函数,以及右操作数不是整数的情况(PostgreSQL 等需要)。

    此更改解决了不同后端上除法运算符行为不一致的问题,并修复了 Oracle 上的整数除法由于不适当的 outputtypehandlers 而无法获取结果的问题。

    参考链接: #4926

  • [sql] [错误修复]

    向编译器添加了一个额外的查找步骤,该步骤将跟踪所有作为表的 FROM 子句,这些表可能在多个模式中共享相同的名称,其中一个模式是隐式的 “默认” 模式;在这种情况下,当引用没有模式限定的名称时,表名将在编译器级别使用匿名别名名称进行渲染,以便消除两个(或多个)名称的歧义。还考虑了使用服务器检测到的 “默认模式名称” 值对通常不限定的名称进行模式限定的方法,但是此方法不适用于 Oracle,也不被 SQL Server 接受,并且也不适用于 PostgreSQL 搜索路径中的多个条目。此处解决的名称冲突问题已被确定为至少影响 Oracle、PostgreSQL、SQL Server、MySQL 和 MariaDB。

    参考链接: #7471

  • [sql] [错误修复]

    Python 字符串值,其 SQL 类型是从值的类型确定的,主要是在使用 literal() 时,对于使用 Python str.isascii() 测试为 “仅 ASCII” 的 Python 字符串值,现在将应用 String 类型,而不是 Unicode 数据类型。如果字符串不是 isascii(),则将绑定 Unicode 数据类型,这在以前的所有字符串检测中都使用过。此行为 仅适用于在使用 ``literal()`` 或其他没有现有数据类型的上下文时对数据类型进行就地检测,这在正常的 Column 比较操作下通常不是这种情况,在这些操作中,被比较的 Column 的类型始终优先。

    使用 Unicode 数据类型可以决定在 SQL Server 等后端上的字面字符串格式,其中字面值(即使用 literal_binds)将呈现为 N'<value>' 而不是 'value'。对于正常的绑定值处理,Unicode 数据类型也可能对将值传递给 DBAPI 产生影响,同样以 SQL Server 为例,pyodbc 驱动程序支持使用 setinputsizes 模式,这将区别对待 StringUnicode

    参考链接:#7551

  • [sql] [bug]

    array_agg 现在会将数组维度设置为 1。改进了 ARRAY 处理,以接受 None 值作为多维数组的值。

    参考链接:#7083

schema

typing

postgresql

  • [postgresql] [feature]

    添加了新的 PostgreSQL DOMAIN 数据类型,其 CREATE TYPE / DROP TYPE 行为与 PostgreSQL ENUM 相同。非常感谢 David Baumgold 为此付出的努力。

    另请参阅

    DOMAIN

    参考链接:#7316

  • [postgresql] [usecase] [asyncpg]

    添加了可重写的方法 PGDialect_asyncpg.setup_asyncpg_json_codecPGDialect_asyncpg.setup_asyncpg_jsonb_codec 编解码器,用于处理在使用 asyncpg 时注册这些数据类型的 JSON/JSONB 编解码器的必要任务。更改是将方法分解为单独的可重写方法,以支持需要更改或禁用如何设置这些特定编解码器的第三方方言。

    此更改也 向后移植 到: 1.4.27

    参考链接:#7284

  • [postgresql] [usecase]

    ARRAYARRAY 数据类型添加了字面类型渲染。通用字符串化将使用方括号渲染,例如 [1, 2, 3],而 PostgreSQL 特定的将使用 ARRAY 字面量,例如 ARRAY[1, 2, 3]。还考虑了多维和引号。

    参考链接:#8138

  • [postgresql] [usecase]

    增加了对 PostgreSQL multirange 类型(PostgreSQL 14 中引入)的支持。现在已将对 PostgreSQL range 和 multirange 的支持推广到 psycopg3、psycopg2 和 asyncpg 后端,并为进一步的方言支持留有空间,使用与之前使用的 psycopg2 对象构造函数兼容的后端无关的 Range 数据对象。请参阅新的文档以了解使用模式。

    此外,范围类型处理已得到增强,使其自动渲染类型转换,因此对于未向数据库提供任何上下文的语句的就地往返,不需要显式使用 cast() 构造函数,以便数据库知道所需的类型(在 #8540 中讨论)。

    非常感谢 @zeeeeeb 提供 pull request,实现了新的数据类型和 psycopg 支持并进行了测试。

    参考链接:#7156#8540

  • [postgresql] [usecase]

    为 psycopg、asyncpg 和 pg8000(但不包括 psycopg2)配置 create_engine.pool_pre_ping 时发出的 “ping” 查询已更改为空查询 (;) 而不是 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,表示默认情况下此数据类型接受 Python UUID 对象。此外,SQL Server UNIQUEIDENTIFIER 数据类型已转换为 UUID 接收类型;对于使用字符串值的 UNIQUEIDENTIFIER 的旧代码,请将 UNIQUEIDENTIFIER.as_uuid 参数设置为 False

    参考链接:#7225

  • [postgresql] [change]

    PostgreSQL 特定的 ENUM 数据类型的 ENUM.name 参数现在是必需的关键字参数。在任何情况下,“name” 都是必要的,以便 ENUM 可用,因为如果 “name” 不存在,则会在 SQL/DDL 渲染时引发错误。

  • [postgresql] [change]

    为了支持新的 PostgreSQL 功能(包括 psycopg3 方言)以及扩展的 “fast insertmany” 支持,已重新设计将绑定参数的类型信息传递到 PostgreSQL 数据库的系统,以使用 SQL 编译器发出的内联转换,并且现在应用于所有 PostgreSQL 方言。这与以前的方法形成对比,以前的方法依赖于正在使用的 DBAPI 本身来渲染这些转换,在 pg8000 和适配的 asyncpg 驱动程序的情况下,将使用 pep-249 setinputsizes() 方法,或者对于 psycopg2 驱动程序,在大多数情况下将依赖于驱动程序本身,但 ARRAY 除外,有一些特殊例外。

    新方法现在让所有 PostgreSQL 方言根据需要在编译器中使用 PostgreSQL 双冒号样式渲染这些转换,并且 PostgreSQL 方言不再使用 setinputsizes(),因为这在任何情况下通常都不是这些 DBAPI 的一部分(pg8000 是唯一的例外,它应 SQLAlchemy 开发人员的要求添加了该方法)。

    此方法的优点包括每个语句的性能,因为在执行时不需要对编译后的语句进行第二次传递,更好地支持所有 DBAPI,因为现在有一个一致的应用类型信息的系统,以及更高的透明度,因为 SQL 日志输出以及编译后的语句的字符串输出将直接显示语句中存在的这些转换,而以前这些转换在日志输出中不可见,因为它们会在语句记录后发生。

  • [postgresql] [bug]

    Operators.match() 运算符现在对 PostgreSQL 全文搜索使用 plainto_tsquery() 而不是 to_tsquery()。此更改的基本原理是提供与在其他数据库后端上匹配的更好的交叉兼容性。通过结合使用 funcOperators.bool_op()Operators.op() 的改进版本,用于布尔运算符),仍然可以完全支持所有 PostgreSQL 全文函数。

    参考链接:#7086

  • [postgresql] [removed]

    删除了对多个已弃用驱动程序的支持

    请切换到受支持的驱动程序之一或同一驱动程序的外部版本。

    参考链接: #7258

  • [postgresql] [dialect]

    添加了对 psycopg 方言的支持,该方言同时支持同步和异步执行。此方言在 create_engine()create_async_engine() 引擎创建函数下以 postgresql+psycopg 名称提供。

    参考链接:#6842

  • [postgresql] [psycopg2]

    更新 psycopg2 方言以使用 DBAPI 接口来执行两阶段事务。以前,执行 SQL 命令来处理此类事务。

    参考链接:#7238

  • [postgresql] [schema]

    引入了可在 cast 表达式中使用的 JSONPATH 类型。某些 PostgreSQL 方言在使用 jsonb_path_existsjsonb_path_match 等接受 jsonpath 作为输入的函数时,需要此类型。

    另请参阅

    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]

    修复了 MySQL Insert.on_duplicate_key_update() 中的问题,当在 VALUES 表达式中使用表达式时,该问题会导致渲染错误的列名。感谢 Cristian Sabaila 提供 Pull request。

    此更改也 向后移植 到: 1.4.27

    参考链接:#7281

  • [mysql] [removed]

    删除了对 MySQL 和 MariaDB 的 OurSQL 驱动程序的支持,因为此驱动程序似乎未得到维护。

    参考链接: #7258

mariadb

  • [mariadb] [usecase]

    添加了新的执行选项 is_delete_using=True,当 ORM 启用的 DELETE 语句与 “fetch” 同步策略结合使用时,ORM 会使用此选项;此选项指示 DELETE 语句预期使用多个表,这在 MariaDB 上是 DELETE..USING 语法。然后,该选项指示对于已知不支持 “DELETE..USING..RETURNING” 语法的数据库(即使它们支持 “DELETE..USING”,这是 MariaDB 当前的功能),不应使用 RETURNING(在 SQLAlchemy 2.0 中为 MariaDB 针对 #7011 新实现)。

    此选项的基本原理是,ORM 启用的 DELETE 的当前工作方式无法预先知道 DELETE 语句是针对多个表还是单个表,直到编译发生(无论如何都会缓存),但需要知道这一点,以便可以预先发出 SELECT 以获取要删除的行。为了避免对所有 DELETE 语句应用全面的性能惩罚,从而主动检查它们是否都存在这种相对不寻常的 SQL 模式,is_delete_using=True 执行选项是通过编译步骤中引发的新异常消息请求的。仅当满足以下条件时,才会专门(且仅)引发此异常消息:该语句是 ORM 启用的 DELETE,其中已请求 “fetch” 同步策略;后端是 MariaDB 或其他具有此特定限制的后端;语句在初始编译中已被检测到,否则将发出 “DELETE..USING..RETURNING”。通过应用执行选项,ORM 知道预先运行 SELECT。为 ORM 启用的 UPDATE 实现了类似的选项,但目前尚无需要它的后端。

    参考资料: #8344

  • [mariadb] [usecase]

    为 MariaDB 方言添加了 INSERT..RETURNING 和 DELETE..RETURNING 支持。MariaDB 尚不支持 UPDATE..RETURNING。MariaDB 从 10.5.0 版本开始支持 INSERT..RETURNING,从 10.0.5 版本开始支持 DELETE..RETURNING。

    参考链接:#7011

sqlite

  • [sqlite] [usecase]

    为 SQLite 反射方法添加了新参数 sqlite_include_internal=True;省略此参数时,以 sqlite_ 前缀开头的本地表(根据 SQLite 文档,这些表被标记为“内部模式”表,例如为支持 “AUTOINCREMENT” 列而生成的 sqlite_sequence 表)将不会包含在返回本地对象列表的反射方法中。这可以防止出现问题,例如在使用 Alembic autogenerate 时,以前会将这些 SQLite 生成的表视为从模型中删除。

    另请参阅

    反射内部模式表

    参考链接:#8234

  • [sqlite] [usecase]

    为 SQLite 方言添加了 RETURNING 支持。SQLite 从 3.35 版本开始支持 RETURNING。

    参考链接:#6195

  • [sqlite] [usecase] [performance]

    SQLite 的 datetime、date 和 time 数据类型现在使用 Python 标准库的 fromisoformat() 方法来解析传入的 datetime、date 和 time 字符串值。这提高了性能,相较于之前基于正则表达式的方法,并且还能自动适应包含六位“微秒”格式或三位“毫秒”格式的 datetime 和 time 格式。

    参考链接:#7029

  • [sqlite] [usecase]

    SQLite 方言现在支持 UPDATE..FROM 语法,用于 UPDATE 语句,该语句可以在语句的 WHERE 条件中引用其他表,而无需使用子查询。当使用 Update 构造,并且使用了多个表或其他实体或 selectable 时,将自动调用此语法。

    参考链接:#7185

  • [sqlite] [bug]

    移除了从 Numeric 类型发出的关于 DBAPI 不原生支持 Decimal 值的警告。此警告是针对 SQLite 的,SQLite 在没有额外扩展或变通方法的情况下,无法真正处理超过 15 位有效数字的精度数值,因为它仅使用浮点数学来表示数字。由于这是 SQLite 本身已知且有文档记录的限制,而不是 pysqlite 驱动程序的怪癖,因此 SQLAlchemy 没有必要为此发出警告。此更改不会以其他方式修改精度数值的处理方式。值可以继续作为 Decimal()float() 处理,具体取决于 NumericFloat 和相关数据类型的配置,只是在使用 SQLite 时,除非使用字符串等替代表示形式,否则无法保持超过 15 位有效数字的精度。

    参考链接:#7299

  • [sqlite] [bug] [performance]

    当使用基于文件的数据库时,SQLite 方言现在默认使用 QueuePool。这与将 check_same_thread 参数设置为 False 一起设置。已经观察到,之前默认使用 NullPool 的方法(它在数据库连接释放后不会保持连接)实际上具有可衡量的负面性能影响。与往常一样,池类可以通过 create_engine.poolclass 参数进行自定义。

    参考链接:#7490

mssql

  • [mssql] [usecase]

    为 SQL Server 方言实现了 “clustered index” 标志 mssql_clustered 的反射。Pull request 由 John Lennox 提供。

    参考链接:#8288

  • [mssql] [usecase]

    在创建表时,为 MSSQL 添加了表和列注释的支持。添加了反射表注释的支持。感谢 Daniel Hall 在此 pull request 中的帮助。

    参考链接:#7844

  • [mssql] [bug]

    现在,mssql+pyodbc 方言的 use_setinputsizes 参数默认设置为 True;这是为了使 pyodbc 将非 unicode 字符串比较绑定到 pyodbc.SQL_VARCHAR 而不是 pyodbc.SQL_WVARCHAR,从而允许针对 VARCHAR 列的索引生效。为了使 fast_executemany=True 参数继续工作,现在 use_setinputsizes 模式在 fast_executemany 为 True 且正在使用的方法是 cursor.executemany() 时,会专门跳过 cursor.setinputsizes() 调用,因为 cursor.executemany() 不支持 setinputsizes。此更改还为类型为 UnicodeUnicodeText 的值添加了适当的 pyodbc DBAPI 类型,并将基本 JSON 数据类型更改为将 JSON 字符串值视为 Unicode 而不是 String

    参考链接:#8177

  • [mssql] [removed]

    由于缺乏测试支持,移除了对 mxodbc 驱动程序的支持。ODBC 用户可以使用完全支持的 pyodbc 方言。

    参考链接: #7258

oracle

  • [oracle] [feature]

    添加了对新的 oracle 驱动程序 oracledb 的支持。

    参考链接:#8054

  • [oracle] [feature]

    实现了对包含显式 “binary_precision” 值的 FLOAT 数据类型的 DDL 和反射支持。使用 Oracle 特定的 FLOAT 数据类型,可以指定新的参数 FLOAT.binary_precision,这将直接呈现 Oracle 浮点类型的精度。此值在反射期间被解释。在反射回 FLOAT 数据类型时,返回的数据类型是 DOUBLE_PRECISION(对于精度为 126 的 FLOAT,这也是 Oracle FLOAT 的默认精度)、REAL(对于精度为 63)和 FLOAT(对于自定义精度),如 Oracle 文档所述。

    作为此更改的一部分,当为 Oracle 生成 DDL 时,显式拒绝了泛型 Float.precision 值,因为此精度无法准确转换为 “binary precision”;相反,错误消息鼓励使用 TypeEngine.with_variant(),以便可以精确选择 Oracle 特定的精度形式。这是一个向后不兼容的行为更改,因为之前的 “precision” 值对于 Oracle 是被静默忽略的。

    参考链接: #5465

  • [oracle] [feature]

    为 cx_Oracle 方言实现了完整的 “RETURNING” 支持,涵盖两种不同的功能类型

    • 实现了多行 RETURNING,这意味着对于生成多行的 RETURNING 的 DML 语句,现在可以接收多行 RETURNING。

    • 还实现了 “executemany RETURNING” - 当使用 cursor.executemany() 时,这允许 RETURNING 为每个语句生成行。此功能部分的实现为 ORM 插入带来了显著的性能提升,与 SQLAlchemy 1.4 更改 ORM 批量插入与 psycopg2 现在在大多数情况下使用 RETURNING 批量处理语句 中为 psycopg2 添加的方式相同。

    参考链接:#6245

  • [oracle] [usecase]

    对于 Oracle 12c 及更高版本,Oracle 现在默认使用 FETCH FIRST N ROWS / OFFSET 语法来支持 limit/offset。当直接使用 Select.fetch() 时,此语法已经可用,现在也隐式地用于 Select.limit()Select.offset()

    参考链接:#8221

  • [oracle] [change]

    Oracle 上的物化视图现在被反射为视图。在以前版本的 SQLAlchemy 中,视图是在表名中返回的,而不是在视图名中。作为此更改的副作用,除非设置了 views=True,否则默认情况下 MetaData.reflect() 不会反射它们。要获取物化视图的列表,请使用新的检查方法 Inspector.get_materialized_view_names()

  • [oracle] [bug]

    根据 Oracle 开发人员的建议,对 cx_Oracle 和 oracledb 方言中的 BLOB / CLOB / NCLOB 数据类型进行了调整,以提高性能。

    参考链接:#7494

  • [oracle] [bug]

    create_engine.implicit_returning 的弃用相关,现在 Oracle 方言在所有情况下都启用了 “implicit_returning” 功能;以前,当检测到 Oracle 8/8i 版本时,该功能会被关闭,但是在线文档表明这两个版本都支持与现代版本相同的 RETURNING 语法。

    参考链接: #6962

  • [oracle]

    cx_Oracle 7 现在是 cx_Oracle 的最低版本。

misc

  • [removed] [sybase]

    移除了在以前的 SQLAlchemy 版本中已弃用的 “sybase” 内部方言。第三方方言支持可用。

    另请参阅

    外部方言

    参考链接: #7258

  • [removed] [firebird]

    移除了在以前的 SQLAlchemy 版本中已弃用的 “firebird” 内部方言。第三方方言支持可用。

    另请参阅

    外部方言

    参考链接: #7258