无发布日期
ORMExecuteState.is_from_statement
,用于检测形式为 select().from_statement()
的语句,并且还增强了FromStatement
以设置 ORMExecuteState.is_select
、ORMExecuteState.is_insert
、ORMExecuteState.is_update
和 ORMExecuteState.is_delete
根据发送到 Select.from_statement()
方法本身的元素。
References: #11220
Connection.execution_options.logging_token
选项中修复了问题,当在已经记录了消息的连接上更改logging_token
的值时,不会更新以反映新的日志令牌。具体来说,这会阻止使用 Session.connection()
来更改连接上的选项,因为 BEGIN 记录消息已经被发出。
References: #11210
ParamSpec
添加到 asyncio 的run_sync()
方法中,使用 AsyncConnection.run_sync()
与 MetaData.reflect()
将会由于错误导致 mypy 失败。详细信息请参阅 github.com/python/mypy/issues/17093
。由 Francisco R. Del Roio 提供的拉取请求。
References: #11200
subprocess.run
时正确初始化PYTHONPATH
变量。
References: #11268
发布日期:2024 年 3 月 23 日
TypeAliasType
构造以及 python 3.12 原生的type
关键字的支持,以便在使用这些构造链接到PEP 593 Annotated
容器时,允许解析Annotated
在这些构造用于Mapped
类型容器时继续进行。
参考:#11130
Relationship
而不是Mapped
来定义关系会意外地为该属性引入“动态”关系加载策略。
参考:#10611
mapped_column()
与mapped_column.index
或mapped_column.unique
设置为 False 时,会被具有该参数设置为True
的传入Annotated
元素覆盖的问题,即使直接的mapped_column()
元素更具体且应优先考虑。增强了协调布尔值的逻辑,以适应本地值为False
仍然优先于来自注释元素的True
值的情况。
参考:#11091
subqueryload()
加载器选项的实现,该加载器选项在内部使用一些更具传统模式的模式,当使用此加载器选项与此加载器选项一起使用附加加载器条件功能时。
参考:#11173
Sequence
并具有显式模式名称的生成器,同时使用 Connection.execution_options.schema_translate_map
功能将无法正确呈现序列或参数,导致错误。
参考: #11157
TypeEngine.with_variant()
方法的问题,该问题在“with_variant()”克隆原始 TypeEngine 而不是更改类型中介绍。该问题未考虑到.copy()
方法,该方法会丢失设置的变体映射。对于“schema”类型的非常特定情况而言,这是一个问题,该类型包括Enum
和ARRAY
等类型,当它们在 ORM Declarative 映射与混入一起使用时,类型的复制就会起作用。现在还复制了变体映射。
参考:#11176
run_sync()
方法正确类型化参数的类型问题,该方法根据传递的可调用函数使用了PEP 612 ParamSpec
变量。感谢 Francisco R. Del Roio 提供的拉取请求。
参考:#11055
DOMAIN
实例。之前,返回的是域数据类型。作为此更改的一部分,改进了域反射以返回文本类型的校对。感谢 Thomas Stephenson 提供的拉取请求。
参考:#10693
asyncio.Runner
或后移的等效版本,而不是依赖于以前基于asyncio.get_running_loop()
的实现。这样做有望防止在 CPU 负载硬件上进行大型测试套件运行时出现问题,其中事件循环似乎会损坏,从而导致级联失败。
参考:#11187
发布日期:2024 年 3 月 4 日
with_expression()
构造中用于缓存键生成的绑定参数值的更改。新的逻辑改变了将新的绑定参数值与语句关联的方法,避免了需要深复制语句的需要,这可能会对非常深/复杂的 SQL 结构造成重大性能损失。新方法不再需要这个深复制步骤。
参考:#11085
and_()
表达式中使用“secondary”表将无法被别名化以匹配“secondary”表在Select.join()
表达式中通常的渲染方式,导致查询无效。
参考:#11010
Connection.execution_options.preserve_rowcount
。设置后,将在语句执行时无条件地将 DBAPI 游标的cursor.rowcount
属性存储,以便无论 DBAPI 为任何类型的语句提供的值都可以使用CursorResult.rowcount
属性从CursorResult
中获取。这允许访问行计数,例如 INSERT 和 SELECT 语句,至少在使用的 DBAPI 支持的程度上。INSERT 语句的“插入多个值”行为也支持此选项,并将在设置时确保为批量插入行时正确设置CursorResult.rowcount
。
参考:#10974
QueuePool
或其他非异步池类传递给 create_async_engine()
,则会引发错误。此引擎仅接受与 asyncio 兼容的池类,包括 AsyncAdaptedQueuePool
。其他池类(例如 NullPool
)与同步和异步引擎都兼容,因为它们不执行任何锁定。
参见
API 文档 - 可用的连接池实现
参考资料:#8771
发布日期:2024 年 2 月 13 日
发布日期:2024 年 2 月 11 日
Mapped
容器类型中使用该类型的问题。现在,用于评估的本地变量范围包括类主体本身。此外,Mapped
内的表达式还可以引用类名本身,如果作为字符串使用或者使用了未来的注释模式。
参考资料:#10899
Session.delete()
与 Mapper.version_id_col
功能时,如果由于对象上使用了 relationship.post_update
而导致目标对象上发出了额外的 UPDATE,则会失败使用正确的版本标识符的问题。这个问题类似于#10800,只是对于仅有更新的情况,版本 2.0.25 中刚刚修复了。
参考:#10967
with_expression()
实现中的断言,如果使用了不可缓存的 SQL 表达式,则会引发断言错误;这是从 1.4 版本以来的一个 2.0 回归。
参考:#10990
MetaData.to_metadata()
复制历史表也会复制索引(这是一件好事),但不管用于这些索引的命名方案如何,都会导致命名冲突。现在这些索引都会添加一个“_history”后缀,方式与表名的方式相同。
参考:#10920
Identity
构造添加到所有表中,并允许在此后端上进行主键生成,修复了 examples/performance 中性能示例脚本在 Oracle 数据库上基本可用的问题。一些“原始 DBAPI” 情况仍与 Oracle 不兼容。
case()
中的问题,即确定表达式类型的逻辑可能导致如果“whens”中的最后一个元素没有类型,或在其他情况下类型可能解析为 None
,则会导致 NullType
。逻辑已更新为扫描所有给定表达式,以便使用第一个非空类型,并始终确保存在类型。感谢 David Evans 提交的拉取请求。
参考:#10843
PoolEvents.checkin()
事件的类型签名,指示给定的 DBAPIConnection
参数在连接无效时可能为 None
的情况。
no_inherit=True
设置为反射数据的键。感谢 Ellis Valentiner 的拉取请求。
引用:#10777
USING <method>
选项用于 PostgreSQL CREATE TABLE
,以指定用于存储新表内容的访问方法。感谢 Edgar Ramírez-Mondragón 的拉取请求。
另请参阅
PostgreSQL 表选项
引用:#10904
Range[T]
和 Sequence[Range[T]]
。引入了实用程序序列 MultiRange
,以允许更好地支持 MULTIRANGE 类型的互操作性。
引用:#9736
Range
或 MultiRange
实例推断数据库类型时,区分 INT4 和 INT8 范围以及多范围类型,如果值适合 INT4,则优先选择 INT4。
terminate()
,没有考虑到优雅的 .close()
尝试因其他原因失败,如连接错误。
引用:#10863
Uuid
数据类型与 Uuid.as_uuid
参数设置为 False 时的问题。ORM 优化的 INSERT 语句(例如,“insertmanyvalues”功能)将不会正确地对齐主键 UUID 值以进行批量 INSERT 语句,导致错误。类似的问题也针对 pymssql 驱动程序进行了修复。
.close()
方法显然不是优雅关闭的。用非标准的 .ensure_closed()
方法替换,该方法是可等待的,并将 .close()
移动到所谓的“终止”情况。
参考:#10893
Uuid
数据类型与 Uuid.as_uuid
参数设置为 False 时的问题。ORM 优化的 INSERT 语句(例如,“insertmanyvalues”功能)将不会正确地对齐主键 UUID 值以进行批量 INSERT 语句,导致错误。类似的问题也针对 PostgreSQL 驱动程序进行了修复。
发布日期:2024 年 1 月 2 日
relationship.post_update
功能和使用 mapper version_id_col 时,后者 UPDATE 语句可能会未能正确使用正确的版本标识符,假定在该刷新中已经发出了一个已经增加了版本计数器的 UPDATE。
参考文献:#10800
any_()
/ all_()
的方式,现在将呈现 NOT (expr)
而不是将等式操作符反转为不等于,允许对这些非典型运算符进行更精细的否定控制。
参考文献:#10817
sqlalchemy.sql.functions
模块的类型提示引起的回归,作为 #6810 的一部分:
AsyncEngine.dispose()
会产生一个新的连接池,该连接池没有完全重新建立对 asyncio 兼容互斥锁的使用,导致在使用类似于 asyncio.gather()
的并发特性时,在 asyncio 上下文中产生死锁,因为它使用了普通的 threading.Lock()
。
这个改变也回溯到了:1.4.51
参考文献:#10813
oracledb
DBAPI 版本。 对于 2.0 系列,这是一个预览版本,当前实现尚未包括对 AsyncConnection.stream()
的支持。 SQLAlchemy 计划改进支持以适用于 2.1 版本。
参考文献:#10679
发布日期:2023 年 12 月 28 日
mapped_column()
构造上使用foreign()
注释会产生没有类型的表达式的问题,这样在实际列初始化时不会更新,导致关系无法适当地确定use_get
的问题。
参考:#10597
MappedAsDataclass
、DeclarativeBase
和DeclarativeBaseNoMeta
使用的__init_subclass__()
方法,使其接受任意的**kw
并将其传播到super()
调用,从而允许更灵活地安排使用__init_subclass__()
关键字参数的自定义超类和混入。感谢 Michael Oliver 提供的拉取请求。
参考:#10732
returning()
部分中使用 Bundle
对象的用例已经得到测试并且完全可用。这在以前从未被明确实现或测试过,并且在 1.4 系列中没有正常工作;在 2.0 系列中,ORM UPDATE/DELETE 缺少了一个实现方法,导致 Bundle
对象无法正常工作。
参考:#10776
MutableList
中的一个回归问题,该问题导致检测序列的例程无法正确地过滤掉字符串或字节实例,从而无法将字符串值分配给特定索引(而非序列值则可以正常工作)。
参考:#10784
URL
对象的用户名和密码部分进行 URL 编码时的问题,在使用 URL.render_as_string()
方法将其转换为字符串时,采用了 Python 标准库 urllib.parse.quote
,同时允许加号和空格保持不变,以便与 SQLAlchemy 的非标准 URL 解析兼容,而不是多年前的遗留自行编写的例程。感谢 Xavier NUNN 提交的拉取请求。
参考:#10662
insert()
构造)的 CTE
进行字符串化或编译时失败的问题,由于错误地检测到了语句整体是一个 INSERT,导致内部错误。
Table
等对象时出现意外模式项的错误报告问题,该问题会错误地处理作为元组传递的参数,导致格式错误。错误消息已经使用 f-strings 进行了现代化处理。
参考:#10654
sqlalchemy.sql.functions
模块完成了 pep-484 类型化。对于针对 func
元素进行的 select()
构造现在应该填充返回类型。
参考:#6810
async_fallback
方言参数现已弃用,并将在 SQLAlchemy 2.1 中删除。这个标志在一段时间内没有被用于 SQLAlchemy 的测试套件。通过使用 greenlet_spawn()
在 greenlet 中运行代码,asyncio 方言仍然可以以同步方式运行。
terminate()
方法丢弃无效的连接时,方言首先会尝试使用带有超时的 .close()
优雅地关闭连接,如果操作仅在异步事件循环上下文中进行。这允许 asyncpg 驱动程序处理最终化 TimeoutError
,包括能够在程序退出后继续运行的情况下关闭长时间运行的查询服务器端。
参考:#10717
greenlet
时运行的能力。现在有一个 tox 目标,其中包含标记“nogreenlet”,该目标将在未安装 greenlet 的情况下运行套件(请注意,它仍然作为 tox 配置的一部分临时安装 greenlet)。
参考:#10747
发布日期:2023 年 11 月 2 日
Session.bulk_insert_mappings.render_nulls
参数,允许 render_nulls=True
作为执行选项。这允许使用参数字典中的 None
值进行批量 ORM 插入,并使用给定的字典键的单个行批处理,而不是将其拆分为每个 INSERT 中省略 NULL 列的批次。
另请参阅
在 ORM 批量 INSERT 语句中发送 NULL 值](…/orm/queryguide/dml.html#orm-queryguide-insert-null-params)
参考:#10575
__allow_unmapped__
指令无法允许具有注释(如Any
或具有特定类型但没有Mapped[]
作为其类型的)的遗留Column
/ deferred()
映射,而无需与定位属性名称相关的错误。
参考:#10516
selectinload()
、lazyload()
一起使用with_expression()
构造时,在后续缓存运行中无法正确替换绑定参数值的问题。
参考:#10570
ClassVar
,但仍然以某种方式引用 ORM 映射类名会导致无法解释为未映射的ClassVar
。
参考:#10472
Interval
数据类型实现了“字面值处理”,允许对间隔值进行字面渲染。感谢 Indivar Mishra 的拉取请求。
参考:#9737
literal_execute=True
时,与其他字面渲染参数的某些组合中多次使用相同绑定参数会导致值渲染错误的问题,这是由于迭代问题引起的。
此更改也被回溯到:1.4.50
参考:#10142
TypeEngine.compare_against_backend()
,这个方法是由非常旧版本的 Alembic 使用的。有关详细信息,请参见github.com/sqlalchemy/alembic/issues/1293
。
AsyncSession.close_all()
的 bug,该方法之前未能正确工作。还添加了函数close_all_sessions()
,它是close_all_sessions()
的等效函数。拉取请求由 Bryan 不可思议提供。
参考:#10421
BIT
数据类型时,修复了“insertmanyvalues”的 SQL 处理。在 asyncpg 上,BIT
显然需要使用一个 asyncpg 特定的BitString
类型,该类型目前在使用此 DBAPI 时被公开,使其与其他所有在此处使用普通位字符串的 PostgreSQL DBAPI 不兼容。在版本 2.1 中的未来修复将会使所有 PG 后端规范化此数据类型。拉取请求由 Sören Oldag 提供。
参考:#10532
connection.ping()
的False
参数,用于禁用不需要的“自动重新连接”功能,在 MySQL 驱动程序和后端中被弃用,并且对于某些版本的 MySQL 原生客户端驱动程序产生警告。它已被 mysqlclient 移除,而对于 PyMySQL 和基于 PyMySQL 的驱动程序,该参数将在某个时间点被弃用并移除,因此使用 API 内省来未来保证这些不同移除阶段的兼容性。
此更改也被回溯到:1.4.50
参考:#10492
True
或False
值指定Column.nullable
,因为 MariaDB 不支持生成列的“NOT NULL”短语。拉取请求由 Indivar 提供。
参考:#10056
aioodbc
驱动程序的支持,该驱动程序建立在 pyodbc 和通用 aio* 方言架构之上。
另请参阅
aioodbc - 在 SQL Server 方言文档中。
参考:#6521
Interval
数据类型中的问题,在 Oracle 实现未用于 DDL 生成,导致day_precision
和second_precision
参数被忽略,尽管此方言支持。感谢 Indivar 的拉取请求。
参考:#10509
发布日期:2023 年 10 月 12 日
Session.get_one()
方法,其行为类似于Session.get()
,但如果未找到具有提供的主键的实例,则引发异常。感谢 Carlos Sousa 的拉取请求。
参考:#10202
Session.close_resets_only
设置为False
将阻止Session
在调用Session.close()
后执行任何其他操作。
添加了新方法Session.reset()
,将会将Session
重置为其初始状态。这是Session.close()
的别名,除非Session.close_resets_only
设置为False
。
参考:#7787
mapped_column()
参数,在使用 pep-593 Annotated
对象内的mapped_column()
对象时未被传递,包括mapped_column.sort_order
,mapped_column.deferred
,mapped_column.autoincrement
,mapped_column.system
,mapped_column.info
等。
此外,在Annotated
中接收的mapped_column()
中仍不支持有数据类参数,例如mapped_column.kw_only
,mapped_column.default_factory
等。当以这种方式在Annotated
中使用这些参数时,现在会发出警告(并且它们继续被忽略)。
参考:#10046,#10369
select()
查询调用Result.unique()
时出现的问题,其中一个或多个列产生的值是“未知可哈希性”,通常在使用像func.json_build_object()
这样的 JSON 函数时没有提供类型时会在返回的值实际上不可哈希时内部失败。在这种情况下,修复了对接收到的对象进行哈希性测试,如果不可哈希,则提出了信息性错误消息。请注意,对于“已知不可哈希性”的值,例如直接使用JSON
或ARRAY
类型时,已经提出了信息性错误消息。
此处的“哈希性测试”修复也适用于传统的Query
,但在传统情况下,几乎所有查询都使用Result.unique()
,因此此处不会发出新的警告;在这种情况下,将继续保持回退到在此情况下使用id()
的传统行为,改进是现在将未知类型(结果证明是可哈希的)进行唯一化,而以前不会。
参考:#10459
implicit_returning=False
参数到映射的Table
,则表示“insertmanyvalues”不能在未提供主键值的情况下使用。
参考:#10453
with_loader_criteria()
不适用于将 ON 子句给定为普通 SQL 比较而不是关系目标或类似的Select.join()
的 bug。
参考:#10365
Mapped
等符号在作为子模块元素引用时无法正确解析的问题,假设是基于字符串或“未来注释”样式注释。
参考:#10412
__allow_unmapped__
声明选项时的类型问题,其中使用集合类型(如list[SomeClass]
)声明的类型与使用 typing 构造List[SomeClass]
声明的类型无法被正确识别的问题。感谢 Pascal Corpet 提供的拉取请求。
参考:#10385
Update.add_cte()
添加的 CTE,以在语句顶部提供所需的 CTE,会发生这种情况。
参考:#10408
DDL
构造不再__repr__()
,因为已删除的on
属性未被容纳。感谢 Iuri de Silvio 提供的拉取请求。
参考:#10443
Values
的参数列表过于严格地与List
绑定而不是Sequence
的问题。感谢 Iuri de Silvio 提供的拉取请求。
参考:#10451
AsyncSession.get.execution_options
参数未传播到底层 Session
并被忽略的问题。
cursor.rowcount
值,以适应像 Pandas 这样硬编码调用 Result.rowcount
的工具。SQLAlchemy 通常仅为 UPDATE/DELETE 语句预加载 cursor.rowcount
,否则传递给 DBAPI,在那里如果没有值可用,则可以返回 -1。但是,mariadb-connector 不支持在关闭游标本身后调用 cursor.rowcount
,而是引发错误。已添加通用测试支持,以确保所有后端支持在结果关闭后允许 Result.rowcount
成功(即返回一个整数值,-1 表示“不可用”)。
参考:#10396
select.fetch()
方法限制行数与 WITH TIES 或 PERCENT 结合时被禁用,导致无法使用带有 TOP / ORDER BY 的有效子查询。
参考:#10458
发布日期:2023 年 9 月 18 日
Update
和 Delete
中的解释,以不干扰传递给语句的目标“from”对象,例如在传递 ORM 映射的 aliased
构造时应在“UPDATE FROM”等短语中保留。像使用“SELECT”语句进行 ORM 会话同步的情况,如与 MySQL/MariaDB 一起使用 UPDATE/DELETE 这种形式仍然会有问题,因此最好在使用此类 DML 语句时禁用 synchonize_session。
参考:#10279
selectin_polymorphic()
加入了新的功能,允许其他加载器选项被捆绑为同级,并且引用其子类中的一个,位于父加载器选项的子选项中。以前,只有当 selectin_polymorphic()
处于查询选项的顶层时才支持此模式。请参阅新文档部分以获取示例。
作为这个改变的一部分,改进了Load.selectin_polymorphic()
方法/加载策略的行为,因此子类加载不会加载来自父表的大多数已加载列,当选项用于已经进行关系加载的类时。以前,只有在顶级类加载时才有效的加载子类列的逻辑。
也请参阅
当 selectin_polymorphic
本身是子选项时应用加载器选项
参考:#10348
Enum
数据类型,接受 None
参数作为 Enum.length
参数,导致在结果 DDL 中生成没有长度的 VARCHAR 或其他文本类型。这允许在模式中存在后,为该类型添加任何长度的新元素。感谢 Eugene Toder 提交的拉取请求。
参考:#10269
aggregate_strings
,它接受一个 SQL 表达式和一个分隔符,将多行字符串连接成单个聚合值。该函数根据后端编译成函数,例如group_concat()
、string_agg()
或LISTAGG()
。感谢 Joshua Morris 提交的拉取请求。
参考:#9873
ColumnElement.like()
,ColumnElement.regexp_match()
,ColumnElement.match()
等)以及纯粹的==
相等,该运算符与字符串比较运算符具有相同的优先级,因此将在跟随字符串匹配运算符的字符串连接表达式中应用括号。这为后端(如 PostgreSQL)提供了便利,其中“regexp match”运算符显然比字符串连接运算符的优先级高。
参考:#9610
hashlib.md5()
的使用,该函数用于在 DDL 语句中为长索引和约束名称生成确定性的四个字符后缀,以包含 Python 3.9+中的usedforsecurity=False
参数,以便于 Python 解释器构建用于受限环境(如 FIPS)时,不将此调用视为与安全问题相关联。
参考:#10342
Values
构造现在将自动为与现有 FROM 子句关联的column
创建代理(即副本)。这使得像values_obj.c.colname
这样的表达式将在colname
作为已与先前的Values
或其他表构造一起使用的column
的情况下生成正确的 FROM 子句。最初认为这可能是一个错误条件的候选项,但很可能这种模式已经被广泛使用,所以现在添加以支持。
参考:#10280
Identity.order
参数的呈现方式,该参数是 Sequence
和 Identity
的一部分,并且不适用于其他后端,例如 PostgreSQL 的后端。未来版本将重命名 Identity.order
、Sequence.order
和 Identity.on_null
参数为 Oracle 特定名称,并弃用旧名称,这些参数仅适用于 Oracle。
此更改也被回溯到:1.4.50
参考:#10207
Mapped
的包含类型协变;这是为了允许更大的灵活性,以适应端用户类型化场景,例如使用协议表示传递给其他函数的特定映射类结构。作为这个改变的一部分,还使依赖和相关类型(如 SQLORMOperations
、WriteOnlyMapped
和 SQLColumnExpression
)的包含类型也是协变的。感谢 Roméo Després 提交的拉取请求。
参考:#10288
MetaData.naming_convention
添加更正式的类型。这个改变阻止了基本命名约定字典通过类型检查,并且已经进行了调整,以便再次接受字符串键的普通字典以及使用约束类型作为键或两者混合使用的字典。
作为这个改变的一部分,还对命名约定字典的较少使用的形式进行了类型化,包括它目前允许 Constraint
类型对象作为键。
参考:#10264,#9284
Visitable
类的__class_getitem__()
方法的类型注释,以接受Any
作为键,而不是str
,这有助于一些 IDE(例如 PyCharm)在尝试为包含通用选择器的 SQL 构造编写类型注释时。感谢 Jordan Macdonald 的拉取请求。
参考:#9878
SQLCoreOperations
的类型问题,以支持从类型的角度来看__hash__()
方法,因为对象(如Column
和 ORM InstrumentedAttribute
)是可散列的,并且在Update
和Insert
构造的公共 API 中用作字典键。先前,类型检查器不知道根 SQL 元素是可散列的。
参考:#10353
Existing.select_from()
的类型问题,该问题阻止了它与 ORM 类的使用。
参考:#10337
create_engine.pool_pre_ping
参数时,用于 PostgreSQL 方言的修订的“ping”会干扰 asyncpg 与 PGBouncer“transaction”模式的使用,因为 asnycpg 发出的多个 PostgreSQL 命令可能会被分解到多个连接中导致错误,由于这个新修订的“ping”周围没有任何事务。现在在事务内调用 ping,与所有其他基于 pep-249 DBAPI 的其他后端隐式使用的方式相同;这确保了为此命令发送的一系列 PG 命令在同一个后端连接上调用,而不会在命令中途跳转到不同的连接。如果使用 asyncpg 方言处于“AUTOCOMMIT”模式,则不使用事务,这仍然与 pgbouncer 事务模式不兼容。
参考:#10226
sqlalchemy.testing.fixtures
。这适用于诸如 pkgutil
等尝试导入所有包中所有安装的模块的检查工具。
参考:#10321
发布日期:2023 年 8 月 15 日
Select.join()
进行关系目标的连接的子查询进行。在诸如 PropComparator.and_()
和其他 ORM 特定情况下使用这些注释。
此更改也被回溯到:1.4.50
参考:#10223
CTE
构造函数,当生成 RECURSIVE 列表时。
参考:#10169
Session.execute()
的执行选项以及本地于 ORM 执行的语句本身的执行选项不会传播到 eager loaders,如 selectinload()
、immediateload()
和 sqlalchemy.orm.subqueryload()
,使得不可能禁用单个语句的缓存或使用 schema_translate_map
用于单个语句,以及使用用户自定义执行选项。已做出更改,使得所有针对 Session.execute()
的面向用户的执行选项都将传播到其他加载器。
作为此更改的一部分,可以通过将 execution_options={"compiled_cache": None}
发送到Session.execute()
来在每个语句范围内为“过度深入”的急加载器警告消除缓存被禁用,这将禁用该范围内所有语句的缓存。
参考:#10231
Comparator.any()
这样的表达式中使用的内部克隆,以生成相关 EXISTS 构造会干扰 SQL 编译器的“笛卡尔积警告”功能,导致 SQL 编译器在所有语句元素都正确连接时发出警告。
参考:#10124
lazy="immediateload"
加载策略在某些情况下会将内部加载令牌放置到 ORM 映射属性中的问题,例如在递归自引用加载中不应发生加载的情况。作为此更改的一部分,lazy="immediateload"
策略现在以与其他急加载器相同的方式尊重 relationship.join_depth
参数进行自引用急加载,其中将其设置为未设置或设置为零将导致自引用的即时加载不会发生,将其设置为一个或更大的值将即时加载直到给定深度。
参考:#10139
attribute_keyed_dict()
之类的基于字典的集合在完全正确地 pickle/unpickle 时未能完全 pickle/unpickle 的问题,导致在 unpickling 后尝试变异此类集合时出现问题。
参考:#10175
aliased()
对加入的继承子类进行列局部操作时,链式调用 load_only()
或其他通配符使用 defer()
会失败的问题。
参考:#10125
select()
构造不会渲染任何仅通过Select.add_cte()
方法添加的 CTE,这些 CTE 在语句中没有被引用。
参考资料:#10167
Query
和 select()
在执行无效操作时的情况。
create_engine.isolation_level
设置为 AUTOCOMMIT
(而不是使用 Engine.execution_options()
方法),如果临时选择了替代隔离级别,那么会在使用 Connection.execution_options.isolation_level
时,无法将“自动提交”恢复到池连接中。
参考资料:#10147
Column
或其他 ColumnElement
时无法恢复正确“比较器”对象的问题,该对象用于生成特定于类型对象的 SQL 表达式。
这个更改也被 回溯 到了:1.4.50
参考资料:#10213
Nullable()
和 NotNullable()
以分别将列或 ORM 类型定义为可为空或不可为空。这些函数在运行时无操作,返回未更改的输入。
参考资料:#10173
Session.execute()
时,返回 CursorResult
Query.with_for_update.of
参数在 Query.with_for_update()
中的类型错误
_DMLColumnArgument
类型进行改进,以传递列表达式
literal()
的重载,因此推断返回类型为BindParameter[NullType]
,其中literal.type_
参数为 None
ColumnElement.op()
添加重载,以便在未提供ColumnElement.op.return_type
时推断类型为Callable[[Any], BinaryExpression[Any]]
ColumnElement.__add__()
的丢失重载
拉取请求由 Mehdi Gmira 提供。 参考:#9185
Session
和AsyncSession
等方法中的问题,例如Session.connection()
在Session.connection.execution_options
参数硬编码为不面向用户的内部类型的情况。
参考:#10182
AsyncConnection.aclose()
作为AsyncConnection.close()
的同义词和AsyncSession.aclose()
作为AsyncSession.close()
的同义词,以提供与 Python 标准库@contextlib.aclosing
构造的兼容性。拉取请求由 Grigoriev Semyon 提供。
参考:#9698
发布日期:2023 年 7 月 15 日
Session
中。这与#6471类似,并且由于在 2.0 系列中删除了cascade_backrefs
,这个问题更加明显。作为#6471的一部分添加的AttributeEvents.append_wo_mutation()
事件现在也会对同一集合的现有成员发出信号,这些成员在该集合的批量设置中存在。
参考:#10089
cascade_backrefs
而未合并到Session
中的问题,将不会发出警告,表明这些对象未包含在刷新中,即使它们是集合的待处理成员;在其他情况下,当要刷新的集合包含将被基本丢弃的非附加对象时,会发出警告。对于 backref 待处理集合成员的警告的添加建立了与可能根据不同的关系加载策略在不同时间基于不同时间刷新或不刷新的集合的更大一致性。
参考:#10090
Query
构造中嵌入一个不包含 ORM 实体的 Core SQL 语句时出现内部属性错误, 在这种情况下,ORM 启用的 UPDATE 和 DELETE 语句。
参考:#10098
Row.t
和 Row.tuple()
重命名为 Row._t
和 Row._tuple()
;这是为了符合所有方法和预定义属性都应采用 Python 标准库 namedtuple
风格的策略,其中所有固定名称都有一个前导下划线,以避免与现有列名称冲突。先前的方法/属性现已被弃用,并将发出弃用警告。
参考:#10093
make_url()
函数添加了对非字符串、非 URL
对象的检测,允许立即抛出 ArgumentError
,而不是稍后引发故障。特殊逻辑确保允许通过模拟 URL
的形式。拉取请求由 Grigoriev Semyon 提供。
参考:#10079
host:port
组合。解析已更新,只有当主机名仅包含字母数字字符,并且只包含点或短划线时(例如,没有斜杠),才将冒号视为表示 host:port
值的标记,后跟一个零个或多个整数的整数标记。在所有其他情况下,将整个字符串视为主机。
参考:#10069
CITEXT
数据类型进行比较时将右侧强制转换为 VARCHAR
的问题,导致右侧未被解释为 CITEXT
数据类型,对于 asyncpg、psycopg3 和 pg80000 方言。这导致 CITEXT
类型在实际使用中基本上无法使用;现已修复此问题,并已更正测试套件以正确断言表达式是否被正确渲染。
参考:#10096
发布日期:2023 年 7 月 5 日
create_engine.schema_translate_map
功能,以便所有语句中的模式名称都现在被标记化,无论指定的名称是否在给定的立即模式翻译映射中,并在执行时回退到原始名称的替换。这两个更改允许在每次运行时使用包含或不包含各种键的模式翻译映射来重复使用已编译的对象,从而允许在每次使用具有不同键集的模式翻译映射时继续运行时缓存 SQL 构造。另外,增加了检测在同一语句的多次调用中获得或失去None
键的 schema_translate_map 字典,这会影响语句的编译,并且与缓存不兼容;针对这些情况引发异常。
References: #10025
ColumnOperators.regexp_match()
不会生成“稳定”缓存键的问题,也就是说,缓存键每次都会改变,导致缓存污染。对于ColumnOperators.regexp_replace()
也存在同样的问题,包括标志和实际替换表达式。现在,标志被表示为固定的修饰符字符串,呈现为安全字符串,而不是绑定参数,并且替换表达式在“binary”元素的主要部分中建立,以便生成适当的缓存键。
请注意,作为此更改的一部分,ColumnOperators.regexp_match.flags
和ColumnOperators.regexp_replace.flags
已修改为仅呈现为文字字符串,而以前它们是呈现为完整的 SQL 表达式,通常是绑定参数。这些参数应始终作为普通的 Python 字符串传递,而不是作为 SQL 表达式构造;不希望在实践中使用 SQL 表达式构造该参数,因此这是一个不向后兼容的更改。
该更改还修改了生成的表达式的内部结构,对于带有或不带有标志的 ColumnOperators.regexp_replace()
,以及对于带有标志的 ColumnOperators.regexp_match()
。可能已经实现了自己的 regexp 实现的第三方方言(在搜索中找不到此类方言,因此影响预计很低)需要调整结构的遍历以适应。
此更改也 被回溯 至:1.4.49
参考:#10042
CacheKey
构造中 __ne__()
运算符未正确实现的问题,导致比较 CacheKey
实例时结果荒谬。
此更改也 被回溯 至:1.4.49
association_proxy()
association_proxy.create_on_none_assignment
添加了新选项;当一个关联代理引用标量关系被赋值为 None
且引用的对象不存在时,通过创建者创建一个新对象。这显然是 1.2 系列中的一个未定义行为,被悄悄移除了。
参考:#10013
sqlalchemy.sql.operators
的独立运算符函数(如 sqlalchemy.sql.operators.eq
)时,改进了类型。
参考:#10054
aliased()
构造中的一些类型问题,以正确接受已用 Table.alias()
别名的 Table
对象,以及对 FromClause
对象作为“selectable”参数的一般支持,因为这是完全支持的。
参考:#10061
native_inet_types=False
,表示 DBAPI 使用的转换器将禁用 PostgreSQL INET
和 CIDR
列的行转换为 Python ipaddress
数据类型,而返回字符串。 这允许编写代码以使用这些数据类型的字符串进行迁移,而无需进行代码更改,只需将此参数添加到 create_engine()
或 create_async_engine()
函数调用中。
另见
网络数据类型
参考:#9945
UUID
列。 这使得 Alembic 能够正确检测现有 MariaDB 数据库中此类列的类型。
参考:#10028
mssql_columnstore=True
的索引上指定。
参考:#7340
Cast
执行到具有显式排序规则的字符串类型时,将在 CAST 函数内部渲染 COLLATE 子句的问题,从而导致语法错误。
参考:#9932
发布日期:2023 年 6 月 23 日
undefer_group()
与 selectinload()
或 subqueryload()
的查询会引发 AttributeError
。 感谢 Matthew Martin 提供的拉取请求。
参考:#9870
Mapped
数据类型的混合使用declared_attr
的情况,而是返回了额外的 ORM 数据类型,如AssociationProxy
。声明式运行时错误地尝试将此注释解释为需要Mapped
并引发错误。
参考:#9957
declared_attr
函数从AssociationProxy
返回类型的类型问题被禁止的问题。
参考:#9957
mapped_column.default
参数时,同时设置init=False
会将此值解释为 Dataclass 默认值,该值将直接分配给新实例的对象,绕过了作为底层Column.default
值生成器的默认生成器的过程。现在检测到这种情况,以保持先前的行为,但对于这种模棱两可的用法会发出弃用警告;要为Column
填充默认生成器,应使用mapped_column.insert_default
参数,该参数与固定名称的mapped_column.default
参数相区分,其名称根据 pep-681 固定。
参考:#9936
Session
“状态更改”系统进行了额外的加固和文档,该系统检测到同时使用 Session
和 AsyncSession
对象的并发使用;在获取来自底层引擎的连接的过程中添加了额外的检查,这是关于内部连接管理的关键部分。
参考:#9973
contains_eager()
加载器选项,以便在查询中正确生效。
参考:#10006
Enum
数据类型在 registry.type_annotation_map
中的支持,该支持是作为 #8859 的一部分首次添加的,在此过程中,如果在映射中使用了带有固定配置的自定义 Enum
,则会失败传递 Enum.name
参数,这将导致 PostgreSQL 枚举无法正常工作,如果枚举值被传递为单个值,则会产生其他问题。逻辑已更新,以便传递“名称”,但也使默认 Enum
不会设置硬编码名称为"enum"
,该默认枚举是针对纯 Python 枚举 enum.Enum 类或其他“空”枚举的。
参考:#9963
relationship()
和其他 MapperProperty
对象同时分配给两个不同的类属性时,会发出警告;只有其中一个属性会被映射。对于此条件,已经为 Column
和 mapped_column
对象设置了警告。
参考:#3532
WriteOnlyMapped
和 DynamicMapped
属性。
引用:#9985
发布日期:2023 年 6 月 10 日
DeferredReflection.prepare()
,使其接受传递给 MetaData.reflect()
的任意 **kw
参数,允许使用诸如反射视图等用例以及传递给方言特定参数。另外,还现代化了 DeferredReflection.prepare.bind
参数,以便将 Engine
或 Connection
作为“bind”参数接受。
引用:#9828
DeclarativeBaseNoMeta
声明基类无法与非映射混合类或抽象类一起使用的问题,而是引发 AttributeError
。
引用:#9862
validates.include_backrefs
的默认值在 validates()
函数中更改为 False
。现在将该默认值恢复为 True
。
引用:#9820
default
值并设置init=False
的 dataclasses 字段将无效。在这种情况下,dataclasses 行为是在类上设置默认值,这与 SQLAlchemy 使用的描述符不兼容。为了支持这种情况,在生成 dataclass 时将默认值转换为default_factory
。
引用:#9879
Mapper
添加属性时已经配置了 ORM 映射属性,或者类上已经存在属性时,将发出弃用警告。先前,对于此情况存在一个非弃用警告,但并非始终一致发出。已改进此警告的逻辑,以便在检测到属性的终端用户替换时发出警告,同时对于内部 Declarative 和其他情况,其中用新的属性替换描述符是预期的情况,不会产生误报。
引用:#9841
registry.map_imperatively()
方法的map_imperatively.local_table
参数上的参数检查,确保只传递Table
或其他FromClause
,而不是已存在的映射类,因为该对象将被进一步解释为新的映射时会导致未定义的行为。
引用:#9869
InstanceState.unloaded_expirable
属性是InstanceState.unloaded
的同义词,现在已弃用;此属性始终是特定于实现的,不应公开。
参考:#9913
create_async_engine.async_creator
参数到create_async_engine()
,其完成了与create_engine.creator
参数相同的目的create_engine()
。这是一个不带参数的可调用对象,提供一个新的 asyncio 连接,直接使用 asyncio 数据库驱动程序。create_async_engine()
函数将在适当的结构中封装驱动程序级别的连接。贡献者 Jack Wotherspoon。
参考:#8215
ARRAY_AGG
时,将NAME
列强制转换为TEXT
。这似乎改善了一些 PostgreSQL 派生产品可能不支持NAME
类型的聚合的兼容性。
参考:#9838
NULLS NOT DISTINCT
唯一索引和唯一约束功能的支持,使用方言选项 postgresql_nulls_not_distinct
。更新反射逻辑以正确考虑此选项。贡献者 Pavel Siarchenia。
参考:#8240
@>
。以前优先级错误,导致针对ANY
或ALL
结构呈现时括号错误。
参考:#9836
ColumnOperators.like.escape
和类似的参数不允许空字符串作为参数,该参数将作为“转义”字符传递;这是 PostgreSQL 支持的语法。贡献者 Martin Caslavsky。
参考:#9907
发布日期:2023 年 5 月 19 日
Session.execute()
和相关方法的情况更加有效的情况,即使是对纯粹的 Core SQL 构造也是如此。然而,这可能会影响到未预期的旧有情况,并且可能更多地成为 2.1 版本的事情。但是,现在“ORM-标志”的规则已经被放宽,因此包含任何 ORM 实体或属性的语句,包括仅在 WHERE / ORDER BY / GROUP BY 子句中的语句,在标量子查询中等等,都将启用此标志。这将导致这样的语句发生“autoflush”,并且还可以通过ORMExecuteState.is_orm_statement
事件级别属性可见。
引用:#9805
Uuid
数据类型,以便在选择“native_uuid”时充分利用 PG 特定的 UUID
方言特定的数据类型,以便包含 PG 驱动程序行为。这个问题因为作为#9618的一部分进行的 insertmanyvalues 改进而显现出来,其中类似于#9739,asyncpg 驱动程序对是否存在数据类型转换非常敏感,当使用此通用类型时,必须调用 PostgreSQL 驱动程序特定的本机 UUID
数据类型,以便进行这些转换。
引用:#9808
发布日期:2023 年 5 月 18 日
JoinedLoader
的实现,以使用更简单的方法,此前它使用了一个在多个线程之间共享的缓存结构。这样做的理由是为了避免潜在的竞争条件,这被怀疑是导致一个特定崩溃的原因,该崩溃已经被多次报告。所讨论的缓存结构最终仍然通过编译的 SQL 缓存“缓存”,因此不会预期性能下降。
参考:#9777
CTE
构造中使用update()
或delete()
后,在select()
中使用会引发CompileError
的回归问题,这是由于执行 ORM 级别更新/删除语句的 ORM 相关规则造成的。
参考:#9767
pep-593
的Annotated
将ForeignKey
(或其他列级约束)放在mapped_column()
中,然后通过模型复制到模型会将每个约束的副本应用到生成的Table
中的Column
中,导致不正确的 CREATE TABLE DDL 以及在 Alembic 下的迁移指令。
参考:#9766
joinedload()
加载器选项时,如果使用额外的关系标准,其中额外的标准本身包含引用联接实体的相关子查询,因此也需要对别名实体进行“调整”,则将排除这种适应,从而为joinedload
生成错误的 ON 子句。
参考:#9779
try_cast()
函数泛化到sqlalchemy.
导入命名空间中,以便第三方方言也可以实现它。在 SQLAlchemy 中,try_cast()
函数仍然是一个仅适用于 SQL Server 的构造,如果在不支持它的后端使用它,则会引发CompileError
。
try_cast()
实现了一个 CAST,其中无法转换的转换返回为 NULL,而不是引发错误。理论上,该构造可以由 Google BigQuery、DuckDB 和 Snowflake 等第三方方言实现,并可能是其他方言。
感谢 Nick Crews 的拉取请求。
引用:#9752
values()
构造中的问题,在标量子查询中使用该构造将导致内部编译错误。
引用:#9772
ENUM.create_type
参数设置为其非默认值 False
时,当复制其所属的 Column
时,它将不会被传播,这在使用 ORM 声明性混合时很常见。
引用:#9773
sys.getsizeof()
函数不在 pypy 上运行的测试问题,在 pypy 上,该函数似乎具有与 cpython 不同的行为。
引用:#9789
发布日期:2023 年 5 月 10 日
from __future__ import annotations
时。
引用:#9717
populate_existing
执行选项未被传播到加载选项,导致现有属性无法被就地刷新。
引用:#9746
joinedload()
/ selectinload()
将无法完全遍历多层次深度的加载问题,后跟具有 with_polymorphic()
或类似构造的中间成员。
引用:#9715
mapped_column()
构造中的问题,当 ORM 映射属性引用相同的 Column
时,如果涉及 mapped_column()
构造,将不会发出“直接多次命名列 X”的正确警告,而是引发内部断言。
参考:#9630
BINARY_DOUBLE
现在是 Double
的子类,而用于 asyncpg 和 pg8000 的内部类型现在正确地是 Float
的子类。
update()
构造会引发内部错误的问题。当前对于没有值的 Update
的行为是生成一个带有空“set”子句的 SQL UPDATE 语句,因此对于这个特定子情况已经保持一致。
Session.get()
和 Session.refresh()
(以及 AsyncSession
上的相应方法)的 Session.get.with_for_update
参数的类型,以接受布尔值 True
和运行时参数接受的所有其他形式。
参考:#9762
ColumnExpressionArgument
作为一个公共类型,指示传递给 SQLAlchemy 构造的面向列的参数,例如 Select.where()
、and_()
等。这可以用于为调用这些方法的最终用户函数添加类型。
参考:#9656
AsyncAttrs
,旨在改进使用 asyncio 的延迟加载器和其他已过期或延迟的 ORM 属性,提供一个简单的属性访问器,为任何 ORM 属性提供一个 await
接口,无论它是否需要发出 SQL。
另请参阅
AsyncAttrs
参考:#9731
await_only()
和 await_fallback()
并发函数中的问题,如果函数抛出 GreenletError
,则给定的可等待对象将保持未等待状态,这可能会导致程序后续出现“未等待”警告。在这种情况下,在抛出异常之前,给定的可等待对象现在将被取消。
LargeBinary
数据类型也需要额外的转换以便与新的批量插入格式一起使用。
参考:#9739
Mutable
中的问题,其中为 ORM 映射属性注册事件会在映射继承子类中重复调用,导致在继承层次结构中调用重复事件。
参考:#9676
发布日期:2023 年 4 月 30 日
aliased()
和hybrid_property()
表达式组合的组合会导致缓存键不匹配,导致缓存键持有实际aliased()
对象,同时又不匹配相等结构的缓存键,填充了缓存。
此更改也已回溯到:1.4.48
参考:#9728
Table
和Column
对象的注释反射问题,其中注释包含控制字符,如换行符。对于这些字符以及扩展的 Unicode 字符在表和列注释中的测试支持也已添加到总体测试中。
参考:#9722
发布日期:2023 年 4 月 26 日
Session
执行 Insert
语句时,在 Insert.values()
中使用 bindparam()
将无法被正确解释,因为新的 ORM 启用的插入功能 没有实现这种用例。
参考:#9583, #9595
Row
进行了一系列性能增强:
__getattr__
方法在行的“命名元组”接口的性能得到了提升;在这个变化中,Row
的实现已经简化,移除了在 1.4 版本及以前的 SQLAlchemy 中特有的构造和逻辑。作为这一变化的一部分,Row
的序列化格式已经略微修改,然而使用之前的 SQLAlchemy 2.0 版本进行 pickle 的行将在新格式中被识别。Pull request 由 J. Nick Koston 提供。
Row
内部进行了进一步的重构,以提高性能。由 Federico Caselli 提供。
URL.normalized_query
属性正常运行的回归问题。
引用:#9682
ColumnCollection
的切片访问支持,例如 table.c[0:5]
、subquery.c[:-1]
等。切片访问返回一个子 ColumnCollection
,方式与传递键元组相同。这是对 #8285 添加的键元组访问的自然延续,其中切片访问用例被省略似乎是一个疏忽。
引用:#8285
RowMapping
的类型标注,以表明它还支持 Column
作为索引对象,而不仅仅是字符串名称。Pull request 由 Andy Freeland 提供。
引用:#9644
Double
类型,在 DDL 时将渲染DOUBLE PRECISION
。这是使用新的 MSSQL 数据类型DOUBLE_PRECISION
实现的,也可以直接使用。
Insert.returning()
子句返回 INSERT 的值时,Decimal
返回类型(例如Numeric
)会返回浮点值,而不是Decimal
对象的问题。
发布日期:2023 年 4 月 21 日
ORMExecuteState.is_column_load
,ORMExecuteState.is_relationship_load
,ORMExecuteState.loader_strategy_path
等,如果 SQL 语句本身是“复合选择”,如 UNION,则会抛出AttributeError
。
此更改还回溯到:1.4.48
参考:#9634
__mapper_args__
特殊方法名时,declared_attr.directive()
修改器未正确地应用于子类的问题,与直接使用declared_attr
相反。这两种构造在运行时行为应该相同。
参考:#9625
with_loader_criteria()
加载器选项进行了改进,允许在不是 ORM 语句本身的顶级语句的 Executable.options()
方法中指示它。示例包括嵌入在诸如 union()
的复合语句中的 select()
,在 Insert.from_select()
构造中,以及在不是 ORM 相关的顶级 CTE 表达式中。
参考:#9635
query_expression()
和 column_property()
构造被记录为只读构造,不能在没有添加 init=False
的情况下与 MappedAsDataclass
类一起使用,而在 query_expression()
中没有可能添加 init
参数,因此这个问题不可避免。这些构造已从数据类的角度进行了修改,假定为“只读”,默认设置 init=False
,并不再包含在 pep-681 构造函数中。column_property()
的数据类参数 init
、default
、default_factory
、kw_only
现已弃用;这些字段不适用于在 Declarative 数据类配置中使用的 column_property()
,因为该构造将是只读的。还为 query_expression()
添加了一个特定于读取的参数 query_expression.compare
;query_expression.repr
已经存在。
参考:#9628
mapped_column()
构造添加了缺失的 mapped_column.active_history
参数。
create_pool_from_url()
和 create_async_pool_from_url()
来自字符串或 URL
传入的输入 url 创建 Pool
实例。
参考:#9613
Insert.returning()
或 UpdateBase.return_defaults()
方法上设置了一个新参数 Insert.returning.sort_by_parameter_order
时生效,通过一种交替的 SQL 形式、客户端参数的直接对应以及在某些情况下降级到逐行运行,将对每个返回行批次应用与主键或其他唯一值的对应关系,这些值可以与输入数据相关联。
预计性能影响将是最小的,因为几乎所有常见的主键场景都适合于在除了 SQLite 之外的所有后端实现参数排序批处理,而“逐行”模式与 1.x 系列中使用的非常沉重的方法相比,具有最少的 Python 开销。对于 SQLite,当使用“逐行”模式时,性能没有区别。
预计通过具有高效的“逐行”INSERT 与 RETURNING 批处理功能,后续可以更容易地将“insertmanyvalues”功能推广到包括 RETURNING 支持但不一定易于保证与参数顺序对应的第三方后端。
另请参阅
将返回的行与参数集相关联
参考:#9603, #9618
ColumnOperators.icontains()
、ColumnOperators.istartswith()
、ColumnOperators.iendswith()
和位运算符 ColumnOperators.bitwise_and()
、ColumnOperators.bitwise_or()
、ColumnOperators.bitwise_xor()
、ColumnOperators.bitwise_not()
、ColumnOperators.bitwise_lshift()
和 ColumnOperators.bitwise_rshift()
添加了类型信息。感谢 Martijn Pieters 的拉取请求。
参考:#9650
selectinload()
)中,PropComparator.and_()
表达式未正确类型化的问题。
参考:#9669
prepared_statement_name_func
连接参数选项。此选项允许传递一个可调用对象,用于自定义执行查询时驱动程序将创建的准备语句的名称。感谢 Pavel Sirotkin 的拉取请求。
另请参阅
使用 PGBouncer 的预准备语句名称
参考:#9608
Range.intersection()
方法。感谢 Yurii Karabas 的拉取请求。
参考:#9509
ENUM
的签名中,恢复了 ENUM.name
参数作为可选参数,因为这是根据给定的 pep-435 Enum
类型自动选择的。
参考:#9611
ENUM
比较时将右侧类型转换为 VARCHAR 的问题,这是由于在诸如 asyncpg 等方言中添加了更明确的转换而导致的 PostgreSQL 类型不匹配错误。
参考:#9621
Uuid
数据类型的问题。
发布日期:2023 年 4 月 5 日
lazy="selectinload"
)与另一个相对端的另一个 eager 加载器结合使用时可能发生的无限循环问题。循环检查已修复以包括别名类关系。
这个变更也被 反向移植 到了:1.4.48
参考:#9590
row_number
添加为保留字。
参考:#9588
fast_executemany
设置为 True
时,已更改用于 SQL Server 的批量 INSERT 策略“executemany”与 pyodbc,使用 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
发布日期:2023 年 3 月 31 日
MappedAsDataclass
混合类或 registry.mapped_as_dataclass()
装饰器时,Python 数据类引发的诸如 TypeError
和 ValueError
等异常现在将在一个 InvalidRequestError
包装器中进行包装,其中包含有关错误消息的信息性上下文,参考 Python 数据类文档作为异常原因的官方来源。
参见
创建<类名>数据类时遇到的 Python 数据类错误
参考:#9563
mapped_column()
构造时,如果包含mapped_column.deferred
参数会引发内部错误的问题。
参考:#9550
column()
对象时发出的警告,以包括任何未在适当属性类型内声明的任意 SQL 表达式,例如column_property()
、deferred()
等。这些属性在类字典中保持不变且未映射。由于这种表达式通常不是预期的内容,因此现在对所有这些否则被忽略的表达式发出警告,而不仅仅是column()
的情况。
参考:#9537
declared_attr()
方法中调用它),会引发内部错误,因为对父类映射器的内部获取将失败,并且对于此失败的指令被无意中在 2.0 中删除。
参考:#9519
MappedAsDataclass
的类组合在一起,其中这些 Mixin 字段本身不是数据类的一部分,现在会发出弃用警告,因为这些字段将在将来的版本中被忽略,因为 Python 数据类的行为是忽略这些字段。类型检查器在 pep-681 下不会看到这些字段。
另请参阅
当将转换为数据类时,属性(s)源自不是数据类的超类。 - 关于背景的理由
使用 Mixins 和抽象超类
参考:#9350
BindParameter.render_literal_execute()
方法在调用带有 ORM 注释的参数时会失败。在实践中,当使用一些类似于 Oracle 的使用“FETCH FIRST”的方言以及使用 Select
构造的 Select.limit()
的组合时,在一些 ORM 上下文中会观察到这种情况,包括如果该语句嵌入在关系 primaryjoin 表达式中时,SQL 编译失败。
参考:#9526
Session
进程中的“惰性=‘raise’”处理,这些处理并非由属性访问触发,Session.delete()
方法现在在遍历关系路径以处理“delete”和“delete-orphan”级联规则时,也将禁用“惰性=‘raise’”处理。以前,没有简单的方法可以通用地调用 Session.delete()
在设置了“惰性=‘raise’”的对象上,以便只加载必要的关系。由于“惰性=‘raise’”主要用于捕获在属性访问时发出的 SQL 加载,因此 Session.delete()
现在被制作成像其他 Session
方法一样,包括 Session.merge()
以及 Session.flush()
以及 autoflush。
参考:#9549
Mapped
指令无法在声明性混合类中使用,而不会尝试让该属性对已经映射了该属性的超类的单个或联合继承子类产生影响,从而产生冲突的列错误和/或警告。
参考:#9564
Insert.from_select.names
进行类型定义,以接受字符串列表或列或映射属性。
参考:#9514
DeclarativeBase
派生的声明性基类会导致映射失败的问题。此外,修复了给定的测试套件,以便通过 Python unittest 运行示例的文档说明现在再次有效。
deferred()
和query_expression()
在与 2.0 样式映射正确配合使用时的类型。
参考:#9536
String
数据类型将与要比较的确切列长度一起转换,导致在比较较小长度的VARCHAR
与较大长度的字符串时进行隐式截断,而不管使用的操作符是什么(例如 LIKE,MATCH 等)。 PostgreSQL 方言现在在呈现这些转换时省略VARCHAR
的长度。
参考:#9511
CHAR
、VARCHAR
、TEXT
),以及二进制BLOB
无法使用零长度明确生成的问题,这在 MySQL 中具有特殊含义。感谢 J. Nick Koston 提出的拉取请求。
参考:#9544
copy
和pop
方法。
参考:#9487
发布日期:2023 年 3 月 18 日
composite()
不允许任意可调用对象作为复合类来源的类型问题。
参考:#9502
CITEXT
。拉取请求由 Julian David Rath 提供。
参考:#9416
发布日期:2023 年 3 月 13 日
attr.impl.active_history=True
的实现。
参考:#9460
Row
进行了带有类型信息的代码重构时。对于纯 Python 版本的 Row
,一个特定的常量被转换为基于字符串的 Enum
,而 cython 版本继续使用整数常量,导致反序列化失败。
参考:#9418
select()
构造中,如果没有给定列而然后在 EXISTS 的上下文中使用,则无法呈现的回归,而是引发了内部异常。虽然一个空的“SELECT”通常不是有效的 SQL,但在 EXISTS 数据库中(例如 PostgreSQL)允许它,在任何情况下,该条件现在不再引发内部异常。
参考:#9440
ColumnElement.cast()
中的类型问题,它不允许独立于 ColumnElement
本身的类型引擎参数,而 ColumnElement.cast()
的目的就是这样。
参考:#9451
"PUBLIC"
模式下无法正确工作的反射错误,例如在 Python 端不能将 PUBLIC 名称指定为小写用于 Table.schema
参数。使用大写的 "PUBLIC"
将起作用,但会导致包括引号的 SQL 查询以及在大写 "PUBLIC"
下索引表,这是不一致的。
参考:#9459
发布日期:2023 年 3 月 5 日
KeyFuncDict
、attribute_keyed_dict()
、column_keyed_dict()
等,以便可以根据提供的数据即时构造这些字典类型;这进一步与诸如 Python 数据类 .asdict()
等工具兼容,后者依赖于直接调用这些类作为普通字典类。
参考:#9418
attribute_mapped_collection()
(现在称为 attribute_keyed_dict()
)。
首先,收集现在不再可用于具有不是普通映射属性的“键”属性;已修复了与描述符和/或关联代理属性相关的属性。
其次,如果事件或其他操作需要访问“key”以便从未加载的映射属性填充字典,那么这也会不适当地引发错误,而不是像 1.4 版本中那样尝试加载属性。这个问题也已经修复。
对于这两种情况,扩展了#8372的行为。#8372引入了一个错误,当作为映射字典键使用的派生键实际上未被赋值时会引发错误。在此更改中,仅在“.key”属性的有效值为None
时才发出警告,无法明确确定这个None
是否是有意的。None
将不再作为映射集合字典键的支持(因为它通常指的是 NULL,表示“未知”)。设置attribute_keyed_dict.ignore_unpopulated_attribute
现在也将导致忽略这样的None
键。
参考:#9424
sqlite
和mssql+pyodbc
方言现在与 SQLAlchemy ORM 的“versioned rows”功能兼容,因为 SQLAlchemy 现在通过计算返回的行数来计算 RETURNING 语句的行数,而不是依赖于cursor.rowcount
。特别是,ORM 版本的行用例(在配置版本计数器文档中有描述)现在应该完全支持与 SQL Server pyodbc 方言一起使用。
Mapper.polymorphic_load
参数的支持,该参数应用于继承层次结构中超过一级的每个映射器,允许通过单个语句为层次结构中的所有类加载列,这些列指示使用 "selectin"
,而不是忽略那些中间类上的元素,尽管它们也指示它们将参与 "selectin"
加载,但它们不是基本的 SELECT 语句的一部分。
参考:#9373
Mapped
名称完全合格,无论是否存在 from __annotations__ import future
。此问题首次在 2.0.0b3 中修复,确认此情况通过测试套件工作,但是测试套件显然没有测试名称 Mapped
完全不存在的行为;字符串解析已更新以确保 ORM 如何使用这些函数。
参考:#8853, #9335
mapped_column.use_existing_column
功能无法工作的问题,如果两个同名列被映射到与列本身的显式名称不同的属性名下。现在,当使用此参数时,属性名称可以不同。
参考:#9332
Result
的 Cython 实现进行了小优化,使用了一个特定 int 值的 cdef 来避免 Python 开销。拉取请求由 Matus Valo 提供。
参考:#9343
Row
对象由于意外依赖不稳定的哈希值而无法在进程间可靠地反序列化的 bug。
参考:#9423
nullslast()
和 nullsfirst()
旧版本函数恢复到 sqlalchemy
导入命名空间中。之前,较新的 nulls_last()
和 nulls_first()
函数是可用的,但是旧版本函数不小心被移除了。
参考:#9390
MetaData
的MetaData.schema
参数时,它是一个字符串。
scoped_session.query_property()
返回的类型,使用了一个新的公共类型QueryPropertyDescriptor
。
参考:#9338
Connection.scalars()
方法未被标记为允许多参数列表的错误,现在支持使用insertmanyvalues
操作。
Insert.values()
和Update.values()
的映射的类型进行了改进,使之更加开放,指示只读Mapping
而不是可写Dict
,后者在键类型过于有限时会出错。
参考:#9376
Numeric
类型对象中添加了缺失的初始化重载,以便 pep-484 类型检查器可以正确解析完整的类型,从Numeric.asdecimal
参数派生,确定将表示Decimal
还是float
对象。
参考:#9391
Select.from_statement()
将不接受text()
或TextualSelect
对象作为有效类型的 bug。此外,修复了columns
方法的返回类型缺失的问题。
参考:#9398
with_polymorphic()
未正确记录类类型的类型问题。
参考:#9340
ExcludeConstraint
中的问题,其中文字值被编译为绑定参数而不是直接的内联值,这是 DDL 所必需的。
参考:#9349
ExcludeConstraint
构造中的问题,如果约束包含文本表达式元素,则在 Table.to_metadata()
等操作中以及在一些 Alembic 方案中无法复制。
参考:#9401
DialectEvents.handle_error()
事件接收异常事件的支持未考虑到诸如 MySQL 和 PostgreSQL 的特定方言的 ping 程序的问题。方言特性已重新设计,使得所有方言都参与事件处理。另外,添加了一个新的布尔元素 ExceptionContext.is_pre_ping
,用于标识此操作是否在预 ping 操作中进行。
对于此版本,实现自定义 Dialect.do_ping()
方法的第三方方言可以选择通过不再捕获异常或检查异常是否为“is_disconnect”,而是直接将所有异常传播出去来选择新的改进行为。现在由默认方言的一个包围方法来检查异常是否为“is_disconnect”,这确保了在测试异常是否为“断开连接”异常之前调用事件挂钩以处理所有异常情况。如果现有的 do_ping()
方法继续捕获异常并检查“is_disconnect”,则它将像以前一样工作,但是如果不将异常传播出去,handle_error
钩子将无法访问异常。
参考:#5648
deterministic
参数会导致旧版 SQLite 版本(3.8.3 之前的版本)失败。版本检查逻辑已经改进以适应此情况。
参考:#9379
Uuid
数据类型中的问题,该问题导致它无法与 pymssql 驱动程序一起工作。由于 pymssql 似乎又开始维护,因此恢复了对 pymssql 的测试支持。
参考:#9414
AutomapBase.prepare()
时,从特定映射类而不是直接从 AutomapBase
调用,当 automap 检测到新表时,不会使用正确的基类,而是使用给定的类,导致映射器尝试配置继承关系。虽然通常情况下应该从基类调用 AutomapBase.prepare()
,但在从子类调用时不应该出现严重问题。
参考:#9367
sqlalchemy.ext.mutable
的回归错误,其中 .pop()
方法的语义发生了变化,使得该方法无法工作。感谢 Nils Philippsen 提交的拉取请求。
参考:#9380
发布日期:2023 年 2 月 17 日
mapped_column.sort_order
,可用于控制 ORM 定义的表中列的顺序,适用于常见用例,如具有应首先出现在表中的主键列的混合类。变更说明在 ORM 声明式以不同方式应用列顺序;使用 sort_order 控制行为 中说明了默认的顺序变更行为(这是所有 SQLAlchemy 2.0 发行版的一部分),以及在使用混合类和多个类时使用 mapped_column.sort_order
控制列顺序的用法(2.0.4 中新增)。
另请参阅
ORM 声明式以不同方式应用列顺序;使用 sort_order 控制行为
参考:#9297
Session.refresh()
方法现在将立即加载在Session.refresh.attribute_names
集合中明确命名的与关系绑定的属性,即使它当前链接到“select”加载程序,通常是一个不会在刷新期间触发的“lazy”加载程序。 “懒加载器”策略现在将检测到操作明确是用户发起的Session.refresh()
操作,该操作明确命名了此属性,然后将调用“immediateload”策略实际发出 SQL 以加载属性。这对于某些 asyncio 情况特别有帮助,其中必须强制加载未加载的惰性加载属性,而不使用实际不支持 asyncio 的惰性加载属性模式。
参考:#9298
Select.from_statement()
构造,如在#9217中“修复”的那样,与使用column_property()
等表达式的 ORM 映射类一起使用,会导致 Core 内部错误,其中它会尝试按名称匹配表达式。修复了 Core 问题,并且还调整了#9217中的修复,以便不会对 DML RETURNING 用例产生影响,其中它增加了不必要的开销。
参考:#9273
EvaluatorCompiler
模块标记为 ORM 私有,并将其重命名为_EvaluatorCompiler
。对于可能依赖于此的用户,名称EvaluatorCompiler
仍然存在,但不支持此用法,并将在将来的版本中删除。
MappedAsDataclass
类和registry.mapped_as_dataclass()
方法添加了新参数dataclasses_callable
,允许使用替代的可调用对象来生成 Python dataclasses.dataclass
。这里的用例是替换为 Pydantic 的 dataclass 函数。对版本 2.0.1 中为#9179添加的 mixin 支持进行了调整,以便将 mixin 的__annotations__
集合重写,不包括Mapped
容器,与映射类一样,以便 Pydantic dataclasses 构造函数不会暴露给未知类型。
另请参阅
与 Pydantic 等替代 Dataclass 提供者集成
参考:#9266
ColumnOperators.in_()
运算符时。这与通常确定二进制表达式类型的方式不一致,通常情况下会首先考虑右侧的实际元素类型,然后再应用左侧的类型。
参考:#9313
Table.autoincrement_column
,该属性返回在列中标识为自增的列。
参考:#9277
hybrid_property.inplace
的新修改器。此修改器提供了一种改变 hybrid_property
的状态的方式,这在 SQLAlchemy 版本 1.2.0 之前的非常早期版本的混合属性中基本上是做的,版本 1.2.0 #3912 改变了这一点,删除了原地突变。现在,在选择加入的基础上恢复了这种原地突变,以允许单个混合具有多个设置的方法,无需命名所有方法相同,也无需仔细“链”不同命名的方法以维护组合。类型工具如 Mypy 和 Pyright 不允许在类上使用同名方法,因此通过此更改恢复了一种简洁的设置混合与类型支持的方法。
另请参阅
使用 inplace 创建符合 pep-484 标准的混合属性
参考:#9321
thick_mode
参数的行为,以使 python-oracledb 方言正确接受 False
作为值。以前,只有 None
会表示应禁用 thick mode。
参考:#9295
发布日期:2023 年 2 月 9 日
typing.Self
的临时解决方案,现在使用了 PEP 673 来处理大多数返回 Self
的方法。由于这个变化,现在需要 mypy>=1.0.0
来对 SQLAlchemy 代码进行类型检查。感谢 Yurii Karabas 提供的拉取请求。
参考:#9254
发布日期:2023 年 2 月 6 日
MapperEvents.after_mapper_constructed()
,提供了一个事件钩子,可以在Mapper
对象完全构建完成后但在调用registry.configure()
之前发生。这允许根据Mapper
的初始配置创建额外映射和表结构的代码,也与声明性配置集成。以前,在使用声明性时,Mapper
对象是在类创建过程中创建的,此时没有记录的方法来运行代码。这个改变立即使得自定义映射方案受益,比如带有历史表的版本控制示例,该示例根据映射类的创建生成额外的映射和表。
参考:#9220
Mapper.iterate_properties
属性和Mapper.get_property()
方法,主要用于内部,不再隐式调用registry.configure()
过程。对这些方法的公开访问非常罕见,而拥有registry.configure()
的唯一好处是允许这些集合中存在“backref”属性。为了支持新的MapperEvents.after_mapper_constructed()
事件,现在可以迭代和访问内部的MapperProperty
对象,而不会触发映射器本身的隐式配置。
更公开的迭代所有映射属性的方式,Mapper.attrs
集合等,仍会隐式调用registry.configure()
步骤,从而使得反向引用属性可用。
在所有情况下,registry.configure()
始终可供直接调用。
参考:#9220
column_property()
下仍然会警告,即使隐式地组合了同名属性。
参考:#9232
Mapper.version_id_col
功能时,对于不支持“rowcount”和“RETURNING”的 SQLite 和其他数据库,将“RETURNING”用于这些列,即使实际上并非如此。
参考:#9228
Select.from_statement()
时的回归,其中仅基于名称匹配列到 SQL 标签的 ORM 语句被禁用,这将阻止具有列名标签的任意 SQL 表达式与要加载的实体匹配,以前在 1.4 和之前的系列中可以工作,因此已恢复了先前的行为。
参考:#9217
DeclarativeBase
继承的类的__init__()
机制的回归。更改使得如果类上没有直接的__init__()
方法,则__init__()
将应用于用户定义的基类。现在已经调整为只有在用户定义的基类的层次结构中没有其他类具有__init__()
方法时才应用__init__()
。这再次允许基于DeclarativeBase
的用户定义的基类包含包含自定义__init__()
方法的混入。
参考:#9249
init=False
)丢失。
参考:#9226
mapped_column()
时在__mapper_args__
中指定Mapper.primary_key
参数。尽管这种用法直接在 2.0 文档中,但Mapper
在这种情况下不接受mapped_column()
构造。这个功能已经适用于Mapper.version_id_col
和Mapper.polymorphic_on
参数。
作为这一变化的一部分,可以在非映射混合类上指定__mapper_args__
属性,而无需使用declared_attr()
,包括引用本地存在于混合类上的Column
或mapped_column()
对象的"primary_key"
条目;声明式还将这些列转换为特定映射类的正确列。这在Mapper.version_id_col
和Mapper.polymorphic_on
参数中已经起���用。此外,"primary_key"
中的元素可以指示为现有映射属性的字符串名称。
参考:#9240
MappedAsDataclass
和registry.mapped_as_dataclass()
,则会引发明确的错误,因为这会导致数据类函数在错误的时间应用于映射类,从而在映射过程中导致错误。
参考:#9211
MapperEvents.after_mapper_constructed()
。
参考:#9220
rollback()
被调用),并且在连接未被显式返回到连接池并且被 Python 垃圾收集拦截时,正常返回到池中,如果垃圾收集操作在 asyncio 事件循环外被调用,则会失败,导致大量堆栈跟踪活动被转储到日志和标准输出中。
恢复了正确的行为,即所有由于未被显式返回到连接池而被垃圾收集的 asyncio 连接都会从池中分离并且被丢弃,同时伴随着一条警告,而不是被返回到池中,因为它们无法可靠地重置。在 asyncpg 连接的情况下,将使用 asyncpg 特定的terminate()
方法来更优雅地结束该连接,而不仅仅是将其丢弃。
此更改包括了一个小的行为变更,希望对调试 asyncio 应用程序有用,其中在 asyncio 连接意外被垃圾收集时发出的警告已经通过将其移出try/except
块并移到finally:
块中而变得稍微更加激进,无论分离/终止操作是否成功,它都会无条件地发出。这也将使得将 Python 警告提升为异常的应用程序或测试套件会将此视为完整的异常抛出,而以前这个警告是不可能作为异常传播的。在此期间需要容忍此警告的应用程序和测试套件应该调整 Python 警告过滤器,以允许这些警告不会被提升为异常。
传统同步连接的行为保持不变,即垃圾收集的连接继续正常返回到池中,而不会发出警告。在未来的主要发布版本中,这可能会发生变化,至少会像为 asyncio 驱动程序发出的类似警告一样发出警告,因为对于池化连接被垃圾收集拦截而未被正确返回到池中是一种使用错误。
参考:#9237
has_table()
,再次使用“DESCRIBE”,当 MySQL 版本 8 在使用不存在的模式名称时引发的特定错误代码是意外的,并且无法解释为布尔结果。
参考:#9251
AS <name> ON DUPLICATE KEY
语法的支持,当使用Insert.on_duplicate_key_update()
时,这对于 MySQL 8 的较新版本是必需的,因为先前使用VALUES()
的语法现在在这些版本中会发出弃用警告。服务器版本检测被用来确定是否应该使用传统的 MariaDB / MySQL < 8 VALUES()
语法,还是新的 MySQL 8 所需的语法。感谢 Caspar Wylie 的拉取请求。
参考:#8626
has_table()
函数,以便对于包含不存在的模式的非 None 模式名称的查询,正确地报告 False;以前,会引发数据库错误。
参考:#9251
发布日期:2023 年 2 月 1 日
of_type()
。以前,当使用Load.options()
时,消息缺乏of_type()
应该使用的信息详细信息,而在直接链接选项时不是这样。即使使用Load.options()
,信息详细信息现在也会发出。
参考:#9182
NewType
的支持,可以在 registry.type_annotation_map
中使用,以及在 Mapped
构造中使用。这些类型将与当前的自定义类型子类相同;它们必须显式出现在 registry.type_annotation_map
中进行映射。
参考资料:#9175
MappedAsDataclass
超类时,层次结构中的所有类(不管它们是否实际上已映射)都将通过 @dataclasses.dataclass
函数运行,因此在映射的子类被转换为数据类时,层次结构中声明的非 ORM 字段将被使用。该行为既适用于使用 __abstract__ = True
映射的中介类,也适用于用户定义的声明基类本身,假设 MappedAsDataclass
作为这些类的超类存在。
这允许像 InitVar
声明这样的非映射属性在超类上使用,而无需在每个非映射类上显式运行 @dataclasses.dataclass
装饰器。新行为被认为是正确的,因为这是当使用超类来指示数据类行为时 PEP 681 实现所期望的。
参考资料:#9179
Literal[]
的支持,可以在 registry.type_annotation_map
中使用,以及在 Mapped
构造中使用。要使用这样的自定义类型,它们必须显式出现在 registry.type_annotation_map
中进行映射。感谢 Frederik Aalund 提交的拉取请求。
作为此更改的一部分,将 Enum
在 registry.type_annotation_map
中的支持扩展为还包括 Literal[]
类型,该类型由字符串值组成,除了 enum.Enum
数据类型之外。如果在 Mapped[]
中使用了一个未在 registry.type_annotation_map
中链接到特定数据类型的 Literal[]
数据类型,那么默认将使用一个 Enum
。
另请参阅
在类型映射中使用 Python Enum 或 pep-586 Literal 类型
参考:#9187
registry.type_annotation_map
中使用 Enum
时,修复了一个问题,即如果根据文档将 Enum.native_enum
参数重写为 False,则该参数将不会正确地复制到映射的列数据类型中。
参考:#9200
DeclarativeBase
类中修复了一个回归,其中注册表的默认构造函数不会应用于基类本身,这与以前的 declarative_base()
构造方式不同。这会阻止具有自己的 __init__()
方法的映射类调用 super().__init__()
以访问注册表的默认构造函数并自动填充属性,而是会命中 object.__init__()
,这会导致在任何参数上引发 TypeError
。
参考:#9171
Annotated
类型的规则集,内部类型将始终检查“Optional”,并将其添加到确定列是否为“nullable”的条件中;如果 Annotated
容器中的类型是可选的(或与 None
联合),则如果没有显式的 mapped_column.nullable
参数覆盖它,将考虑该列为可空。
参考:#9177
DropSchema
,这在修复中被无意中忽略,允许在没有方言的情况下进行字符串化。这两个构造的修复已经回溯到 1.4.47 版本的 1.4 系列。
参考:#7664
insert()
时会出现内部TypeError
的情况;为此情况进行了额外的修复,适用于像 asyncpg 这样的位置方言在使用“insertmanyvalues”时。
参考:#9173
Select.with_for_update.of
的类型,也接受表和映射类参数,似乎适用于 MySQL 方言。
参考:#9174
Select.limit()
、Select.offset()
、Query.limit()
、Query.offset()
,允许None
,这是“取消”当前限制/偏移的文档化 API。
参考:#9183
mapped_column()
对象被类型化为Mapped
时不会被接受在模式约束中,如ForeignKey
、UniqueConstraint
或Index
。
参考:#9170
ColumnElement.cast()
的类型检查,以接受 Type[TypeEngine[T]]
和 TypeEngine[T]
;先前只接受 TypeEngine[T]
。拉取请求由 Yurii Karabas 提供。
参考资料:#9156
发布日期:2023 年 1 月 26 日
set_shard_id
添加了新选项,该选项设置了要针对其进行查询的有效分片标识符,包括主查询以及所有次要加载程序,包括关系急加载程序以及关系和列延迟加载程序。
参考资料:#7226
AutomapBase
添加了新功能,用于跨多个模式自动加载类,这些类可能具有重叠的名称,方法是提供一个 AutomapBase.prepare.modulename_for_table
参数,允许自定义新生成的类的 __module__
属性,以及一个新集合 AutomapBase.by_module
,它存储了基于 __module__
属性的类的点分隔的模块名称空间。
此外,现在可以任意次调用 AutomapBase.prepare()
方法,无论是否启用了反射;在每次调用时,只会处理之前未映射的新添加的表。先前,需要显式调用 MetaData.reflect()
方法。
另请参阅
从多个模式生成映射 - 同时演示两种技术的使用。
参考资料:#5145
CreateSchema
DDL 构造的字符串化问题,当没有方言时,会导致AttributeError
。更新:请注意,此修复未考虑到DropSchema
;版本 2.0.1 中的后续修复解决了这个问题。这两个元素的修复已经回溯到 1.4.47。
参考:#7664
func
命名空间中可用的内置通用函数添加了类型,这些函数接受一组特定的参数并返回特定的类型,例如count
,current_timestamp
等。
参考:#9129
StatementLambdaElement
是Executable
层次结构的一部分,因此它被类型化为被Connection.execute()
接受。
参考:#9120
ColumnOperators.in_()
和ColumnOperators.not_in()
方法的类型现在包括Iterable[Any]
,而不是Sequence[Any]
,以提供更灵活的参数类型。
参考:#9122
or_()
和 and_()
需要第一个参数存在,但这些函数仍然接受零个参数,这将在运行时发出弃用警告。还添加了类型支持,以支持将固定字面量False
用于or_()
和 True
用于and_()
作为唯一的第一个参数,但文档现在指示在这些情况下发送false()
和 true()
构造作为更明确的方法。
参考:#9123
Query
对象进行迭代时类型不正确的问题。
参考:#9125
Result
作为上下文管理器时对象类型未被保留的问题,始终指示所有情况下的Result
而不是特定的Result
子类型。感谢 Martin Baláž 的拉取请求。
参考:#9136
relationship.remote_side
和类似参数时的问题,传递作为Mapped
类型的注释声明对象将不被类型检查器接受。
参考:#9150
isnot()
、notin_()
等旧操作符添加了类型,这些操作符以前引用了更新的操作符,但它们本身没有被类型化。
参考:#9148
cursor.rowcount
值用于 SELECT 语句。虽然这不是cursor.rowcount
的典型用法,但其他 PostgreSQL 方言通常提供此值。感谢 Michael Gorven 的拉取请求。
此更改也回溯到:1.4.47
参考:#9048
mysql_length
字典。
此更改也回溯到:1.4.47
参考:#9047
supports_comments
,默认值为None
,表示应自动检测注释支持。当设置为True
或False
时,注释支持将被无条件启用或禁用。
另请参阅
DDL 注释支持
参考:#9142
发布日期:2023 年 1 月 18 日
Mapper
添加了一个名为Mapper.polymorphic_abstract
的新参数。该指令的目的是让 ORM 不考虑该类被直接实例化或加载,只考虑子类。实际效果是,Mapper
将阻止直接实例化该类的实例,并期望该类没有配置独特的多态标识。
在实践中,使用Mapper.polymorphic_abstract
映射的类可以作为relationship()
的目标,也可以在查询中使用;当然,子类必须在映射中包含多态标识。
新参数会自动应用于继承AbstractConcreteBase
类的类,因为这个类不打算被实例化。
另请参阅
使用多态抽象构建更深层次的层次结构
参考:#9060
registry.type_annotation_map
中使用 pep-593 Annotated
类型,其本身包含一个通用的普通容器或collections.abc
类型(例如 list
, dict
, collections.abc.Sequence
等)作为目标类型时会在 ORM 尝试解释Annotated
实例时产生内部错误的问题。
参考:#9099
relationship()
映射到抽象容器类型(例如Mapped[Sequence[B]]
)时未提供relationship.container_class
参数时,添加了一个错误消息,此参数在类型为抽象时是必需的。以前,抽象容器会在稍后的步骤中尝试实例化并失败。
参考:#9100
Update.values()
方法中的列相同名称的bindparam()
,以及在 2.0 中的 Insert.values()
方法中,如果在构造的语句中使用相同名称的参数,则在某些情况下会静默失败,替换为同名的新参数,并丢弃 SQL 表达式的其他元素,例如 SQL 函数等。特定情况将是针对 ORM 实体而不是普通Table
实例构造的语句,但如果使用 Session
或 Connection
调用语句,则会发生。
Update
部分的问题既存在于 2.0 中也存在于 1.4 中,并被回溯到 1.4。
此更改还被回溯到:1.4.47
参考:#9075
sqlalchemy.ext.hybrid
扩展中注释的问题,以更有效地对用户定义的方法进行类型化。现在,typing 使用PEP 612功能,最近的 Mypy 版本也支持,以维护hybrid_method
的参数签名。 混合方法的返回值在Select.where()
等上下文中被接受为 SQL 表达式,同时仍支持 SQL 方法。
参考:#9096
@Backend.mapper_registry.mapped
)中引用,则会发生。 现在,此场景被忽略; 使用插件时,装饰器表达式需要是两个组件(即@reg.mapped
)。
此更改还回溯到:1.4.47
参考:#9102
TIMESTAMP WITH LOCAL TIME ZONE
的支持,使用新添加的 Oracle 特定的TIMESTAMP
数据类型。
参考:#9086
Released: January 9, 2023
TableClause
对象的映射,例如在 wiki 上使用的视图配方中使用的那些。
参考:#9071
field_descriptors
在 PEP 681 的已接受版本中更名为field_specifiers
。
参考:#9067
JSONB
operations:
@@
使用Comparator.path_match()
@?
使用Comparator.path_exists()
#-
使用Comparator.delete_path()
感谢 Guilherme Martins Crocetti 提供的拉取请求。 参考文献:#7147
Inspector.has_table()
的行为,以报告 MySQL / MariaDB 的临时表。这是所有其他包含的方言当前的行为,但是在 1.4 中由于不再使用 DESCRIBE 命令而删除了 MySQL 的该行为;在此版本或任何以前的版本上都没有记录支持通过Inspector.has_table()
方法报告临时表的文件,因此以前的行为未定义。
由于 SQLAlchemy 2.0 已经为临时表状态添加了正式支持通过Inspector.has_table()
,因此 MySQL / MariaDB 方言已恢复为使用“DESCRIBE”语句,就像 SQLAlchemy 1.3 系列和以前一样,并且添加了测试支持以包含 MySQL / MariaDB 的此行为。由于 SQLAlchemy 2.0 中Connection
如何处理事务的简化,1.4 试图改进的 ROLLBACK 引发的先前问题不适用。
DESCRIBE 是必需的,因为 MariaDB 特别是没有任何一致可用的公共信息模式以报告临时表,除了依赖于抛出错误以报告无结果的 DESCRIBE/SHOW COLUMNS。
参考文献:#9058
ForeignKeyConstraint
时,通常生成的错误被禁用,并且与已存在的具有类似问题的Index
一样,跳过该约束并发出警告。
参考:#9059
发布日期:2022 年 12 月 28 日
platform.architecture()
以检测某些系统属性的回归错误,结果是对系统级别的file
调用进行了过于广泛的系统调用,在某些情况下不可用,包括某些安全环境配置中。
此更改也已被回溯到:1.4.46
参考:#8995
Mapper.eager_defaults
参数“auto”的值,这将在工作单元刷新期间自动获取表默认值,如果方言支持 INSERT 的 RETURNING,以及可用的 insertmanyvalues。对于服务器端 UPDATE 默认值的及时获取,这是非常罕见的,只有当Mapper.eager_defaults
设置为True
时才会发生,因为对于 UPDATE 语句没有批量 RETURNING 形式。
参考:#8889
Session
的可扩展性调整,以及ShardedSession
扩展的更新:
Session.get()
现在接受Session.get.bind_arguments
,特别是在使用水平分片扩展时可能会有用。
Session.get_bind()
接受任意关键字参数,这有助于开发使用覆盖此方法的 Session
类的代码,该方法具有附加参数。
identity_token
,它可用于直接影响与新加载的 ORM 对象关联的“身份令牌”。这个令牌是分片方法(主要是ShardedSession
,但也可以在其他情况下使用)在不同“分片”之间分离对象标识的方式。
另见
身份令牌
SessionEvents.do_orm_execute()
事件钩子现在可以用于影响所有与 ORM 相关的选项,包括autoflush
、populate_existing
和yield_per
;这些选项在事件钩子被调用后重新消耗,然后才被执行。以前,像autoflush
这样的选项在这一点上已经被评估过了。新的identity_token
选项也在这种模式下受支持,并且现在被水平分片扩展使用。
ShardedSession
类用新的钩子ShardedSession.identity_chooser
替换了ShardedSession.id_chooser
钩子,不再依赖于传统的Query
对象。在替代ShardedSession.identity_chooser
时,会发出弃用警告,仍然接受ShardedSession.id_chooser
。
参考:#7837
Session
如何适应已经建立事务和可能已经建立保存点的传入Connection
。新参数Session.join_transaction_mode
包括一系列选项值,可以以多种方式适应现有事务,最重要的是允许Session
以完全事务方式操作,仅使用保存点,同时在任何情况下保持外部启动的事务未提交且活动,允许测试套件回滚测试中发生的所有更改。
此外,对Session.close()
方法进行了修订,以完全关闭可能仍存在的保存点,这也允许“外部事务”配方在Session
未明确结束其自身 SAVEPOINT 事务时继续进行而不产生警告。
另请参阅
会话的新事务加入模式
参考:#9015
Mapped[]
注释时必须使用__allow_unmapped__
属性的要求;以前,如果检测到旨在支持遗留 ORM 类型映射的错误消息将被引发,此外还未提及与 Dataclasses 特别相关的正确模式。如果使用了registry.mapped_as_dataclass()
或MappedAsDataclass
,则不再引发此错误消息。
另请参阅
使用非映射数据类字段
参考:#8973
Update
和Delete
等 DML 语句,这将导致除其他潜在问题之外,使用 ORM 更新/删除功能的 lambda 语句的特定问题。
此更改也被回溯到:1.4.46
参考:#9033
Session.merge()
无法保留使用relationship.viewonly
参数指示的关系属性的当前加载内容,从而破坏了使用Session.merge()
从缓存和其他类似技术中拉取完全加载的对象的策略。在相关更改中,修复了一个问题,即包含已配置为在映射上lazy='raise'
的已加载关系的对象在传递给Session.merge()
时会失败;假设Session.merge.load
参数保持其默认值True
,则合并过程中的“raise”检查现在被暂停了。
总体而言,这是对 1.4 系列中引入的更改的行为调整,截至#4994,该更改将“merge”从“viewonly”关系的默认级联集中移除。由于“viewonly”关系在任何情况下都不会被持久化,因此在“merge”期间允许其内容传输不会影响目标对象的持久化行为。这使得Session.merge()
能够正确地适用于其用例之一,即将在其他地方加载的对象添加到Session
中,通常是为了从缓存中恢复。
此更改也被回溯到:1.4.45
参考:#8862
with_expression()
中的问题,在某些情况下,由于表达式由从外部 SELECT 中引用的列组成,因此不会正确地在某些上下文中呈现 SQL,在表达式具有与使用query_expression()
的属性匹配的标签名称的情况下,即使query_expression()
没有默认表达式。暂时,如果query_expression()
确实具有默认表达式,则仍将使用该标签名称作为该默认表达式,并且将继续忽略具有相同名称的其他标签。总体而言,这种情况相当棘手,因此可能需要进一步调整。
此更改还回溯到:1.4.45
参考:#8881
relationship()
中使用的反向引用名称在目标类上命名了已经有方法或属性分配给该名称的属性,则会发出警告,因为反向引用声明将替换该属性。
参考:#4629
Session.refresh()
的变更和改进。总体变更是,当要刷新与关系绑定的属性时,对象的主键属性现在无条件地包含在刷新操作中,即使未过期,即使未在刷新中指定。
Session.refresh()
,以便如果启用了自动刷新(如Session
的默认值),则自动刷新将在刷新过程的较早部分发生,以便应用待处理的主键更改而不会引发错误。以前,此自动刷新发生得太晚,并且 SELECT 语句不会使用正确的键来定位行,并且会引发InvalidRequestError
。
InvalidRequestError
,要求首先刷新待处理的主键更改。以前,这种用例简单地被破坏,无论如何都会引发InvalidRequestError
。这个限制是为了安全起见,以便刷新主键属性,这对于能够刷新具有 relationship 绑定的次要急切加载器的对象是必要的。无论是否实际上需要刷新 PK 列,这个规则都适用于保持 API 行为一致,因为在任何情况下,刷新对象的某些属性而保留其他属性“待处理”是不寻常的。
Session.refresh()
方法已经得到增强,以便刷新那些在映射时或通过最近使用的加载器选项与relationship()
绑定并链接到急切加载器的属性,在所有情况下都会被刷新,即使传递了一个不包括父行上任何列的属性列表。这是在 1.4 中作为#1763的一部分首次实现的功能,允许急切加载的与 relationship 绑定的属性参与Session.refresh()
操作。如果刷新操作没有指示要刷新父行上的任何列,则主键列仍将包括在刷新操作中,这允许加载继续到正常情况下指示的次要关系加载器。以前,对于这种情况会引发一个InvalidRequestError
错误(#8703)
Session.refresh()
与一组过期属性以及像selectinload()
这样发出“secondary”查询的急加载器一起调用时,会发出不必要的额外 SELECT 的情况,如果主键属性也处于过期状态。由于主键属性现在自动包含在刷新中,因此当关系加载器开始为它们选择时,这些属性不会有额外的加载(#8997)。
Session.refresh()
方法将在传递过期的列名以及链接到“secondary” eagerloader(如selectinload()
)的关系绑定属性的名称时失败,并引发AttributeError
(#8996)。
Mapper.with_polymorphic
参数时渲染 ORM 查询。这些适配器非常复杂且容易出错,现在仅在使用用户提供的显式子查询用于Mapper.with_polymorphic
的情况下使用,其中包括仅使用polymorphic_union()
辅助程序的具体继承映射的用例,以及在不需要的现代用例中使用别名子查询的联合继承映射的传统用例。
对于使用内置多态加载方案的联合继承映射的最常见情况,其中包括使用Mapper.polymorphic_load
参数设置为inline
的情况,现在不再使用多态适配器。这对查询构造的性能有积极影响,同时也极大简化了内部查询渲染过程。
目标特定问题是允许column_property()
引用标量子查询中的联合继承类,现在其工作方式尽可能直观。
参考:#8168
Timeout
条件相结合时发生,其中由于超时而中断的连接池检出将无法清理失败的状态,导致底层连接记录以及有时是数据库连接本身“泄漏”,将池留在无效状态中,无法访问条目。这个问题首次在 SQLAlchemy 1.2 中被识别和修复,用于 #4225,然而在该修复中检测到的故障模式未能适应 BaseException
,而不是 Exception
,这导致无法捕获 eventlet/gevent Timeout
。此外,在初始池连接中还确定了一个块,并通过 BaseException
-> “清除失败的连接”块来加固,以适应在此位置的相同条件。非常感谢 Github 用户 @niklaus 在识别和描述这个复杂问题方面的顽强努力。
此更改也被回溯到:1.4.46
参考:#8974
Result.freeze()
方法在使用text()
或Connection.exec_driver_sql()
时无法工作的问题。
此更改也被回溯到:1.4.45
参考:#8963
JSON
元素的比较等)缺乏类型信息。
此更改也被回溯到:1.4.46
参考:#9029
regexp_replace()
函数、首次在#4123中引入的 CTE
构造的“嵌套”特性,以及使用 Oracle 的 FunctionElement.column_valued()
方法形成的可选择表。
此更改也被回溯到:1.4.45
参考:#8827
Compiler
实现中的所有编译器visit_xyz()
方法都接受 **kw
参数,以便所有编译器在所有情况下都接受额外的关键字参数。
参考:#8988
SQLCompiler.construct_params()
方法以及SQLCompiler.params
访问器现在将返回与使用 render_postcompile
参数编译的编译语句对应的确切参数。之前,该方法返回的参数结构本身既不对应原始参数也不对应扩展参数。
不再允许将新参数字典传递给使用 render_postcompile
构造的SQLCompiler
的 SQLCompiler.construct_params()
;相反,为了为另一组参数制作新的 SQL 字符串和参数集,添加了一个新方法 SQLCompiler.construct_expanded_state()
,该方法将使用包含新的 SQL 语句和新的参数字典的 ExpandedState
容器产生给定参数集的新扩展形式,以及一个位置参数元组。
参考:#6114
SQLCompiler.bindname_escape_chars
字典,可以在任何 SQLCompiler
子类的类声明级别进行覆盖。作为此更改的一部分,还将点号 "."
添加为默认的 “转义” 字符。
引用:#8994
sqlalchemy.ext.horizontal_shard
扩展以及 sqlalchemy.orm.events
模块的类型标注。感谢 Gleb Kisenkov 的努力。
引用:#6810, #9025
AsyncResult
中删除了不起作用的 merge()
方法。这个方法从未起作用,是错误地包含在 AsyncResult
中的。
此更改还 反向移植 至:1.4.45
引用:#8952
Insert.on_conflict_do_update.constraint
参数会接受一个 Index
对象,但是不会将此索引展开为其各个索引表达式,而是在 ON CONFLICT ON CONSTRAINT 子句中呈现其名称,这在 PostgreSQL 中不被接受;“约束名”形式仅接受唯一或排除约束名。该参数继续接受索引,但现在会将其展开为其组件表达式以进行呈现。
此更改还 反向移植 至:1.4.46
引用:#9023
format_type()
函数返回 NULL 的替代后端。
此更改还 反向移植 至:1.4.45
引用:#8748
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
INT4RANGE
自定义类型的实现,而是引发 TypeError
的回归问题。
参考:#9020
Range.__eq___()
现在会返回 NotImplemented
,而不是引发 AttributeError
异常。
参考:#8984
FunctionElement.column_valued()
语法不正确的问题,导致 COLUMN_VALUE
名称没有正确限定源表。
此更改还被反向移植至:1.4.45
参考:#8945
unusual_column_name_characters
,可以将其关闭,以防第三方方言不支持具有不寻常字符的列名,例如点、斜杠或百分号,即使名称已正确引用。
此更改还被反向移植至:1.4.46
参考:#9002
发布日期:2022 年 12 月 5 日
mapped_column.use_existing_column
以适应单表继承映射的用例,该映射使用一个以上的子类指示相同的列位于超类上。以前可以通过在超类的 .__table__
中使用 declared_attr()
与定位现有列的方法来实现此模式,但现在已更新为使用 mapped_column()
以及 pep-484 类型提示,以一种简单而简洁的方式。
另请参阅
使用 use_existing_column 解决列冲突
参考:#8822
enum.Enum
基类,以便在使用注释式声明表功能时自动解析为 SQLAlchemy 的 Enum
SQL 类型。该功能通过向 ORM 类型映射功能添加的新查找功能实现,并包括对默认生成的 Enum
的参数进行更改的支持,以及设置映射中特定的 enum.Enum
类型及其特定参数的支持。
另请参阅
在类型映射中使用 Python Enum 或 pep-586 字面类型
参考:#8859
mapped_column()
,relationship()
等)添加了mapped_column.compare
参数,以提供 Python 数据类field()
的compare
参数,当使用声明性数据类映射功能时。感谢 Simon Schiele 的拉取请求。
参考:#8905
aliased()
与union()
和类似“复合”结构的组合,以及对 ORM 频繁使用的corresponding_column()
内部方法的直接性能改进,例如aliased()
和类似构造。
参考:#8796
Mapped
注释中使用未知数据类型时静默失败而不是报告异常的问题;现在会引发一个信息性异常消息。
参考:#8888
Mapped
的情况,例如Mapped[Dict[str, str] | None]
,在声明性 ORM 映射中将不会被正确解释。已修复以正确“去可选化”此类型的支持,包括用于在type_annotation_map
中查找的支持。
参考:#8777
__allow_unmapped__
指令的普通数据类字段时,不会为这些字段创建具有正确类级状态的数据类,不适当地在数据类自身已经用类级默认值替换Field
对象后将原始Field
对象复制到类中。
参考:#8880
Mapper.eager_defaults
参数,将会失败。
参考:#8812
sqlalchemy.orm.Mapped
)指示 Mapped
名称将无法被 Declarative 认为指示 Mapped
结构。
参考:#8853
association_proxy()
扩展函数的支持,以在 Python dataclasses
配置中参与,使用了声明性数据类映射中描述的原生数据类功能。包括属性级参数,包括 association_proxy.init
和 association_proxy.default_factory
。
关联代理的文档也已更新,以在示例中使用 “带注解的声明性表格” 表单,包括用于 AssocationProxy
本身的类型注解。
参考:#8878
ScalarValues
,可用作列元素,允许在 IN
子句中使用 Values
,或与 ANY
或 ALL
集合聚合一起使用。此新类是使用方法 Values.scalar_values()
生成的。当在 IN
或 NOT IN
操作中使用时,现在会将 Values
实例强制转换为 ScalarValues
。
参考:#6289
numeric
pep-249 paramstyle 的方法已被重写,并且现在得到了完全支持,包括“扩展 IN”和“insertmanyvalues”等功能。参数名称也可以在源 SQL 构造中重复,这将在数值格式内正确表示为单个参数。引入了一个名为numeric_dollar
的附加数值 paramstyle,它是由 asyncpg 方言使用的; 该 paramstyle 等效于numeric
,只是数字指示器使用美元符号而不是冒号。asyncpg 方言现在直接使用numeric_dollar
paramstyle,而不是首先编译为format
样式。
numeric
和numeric_dollar
paramstyles 假设目标后端能够以任何顺序接收数字参数,并将给定的参数值与语句匹配,基于将它们的位置(从 1 开始)与数字指示器进行匹配。这是numeric
paramstyles 的正常行为,尽管观察到 SQLite DBAPI 实现了一个不使用的numeric
样式,它不遵守参数排序。
参考:#8849
RETURNING
的渲染,特别是在使用Insert
时,现在会像Select
构造一样渲染列,以生成标签,其中将包括消除歧义的标签,以及将命名列周围的 SQL 函数标记为列名本身。这在从Select
构造或使用UpdateBase.returning()
的 DML 语句中选择行时建立了更好的跨兼容性。1.4 系列还做了一项较窄的范围更改,仅调整了函数标签问题。
参考:#8770
Column
对象附加到 Table
对象,现在有更严格的规则,将一些先前的弃用警告转移到异常,并阻止一些先前可能导致表中出现重复列的情况,当设置 Table.extend_existing
为 True
时,无论是在编程式 Table
构建还是在反射操作期间。
请参阅相同名称、键的表对象中列替换规则更严格以了解这些更改的概述。
另请参阅
相同名称、键的表对象中列替换规则更严格
参考:#8925
SQLColumnExpression
,可以在用户代码中表示任何 SQL 列导向表达式,包括基于 ColumnElement
和 ORM QueryableAttribute
的表达式。这个类型是一个真正的类,而不是别名,因此也可以用作其他对象的基础。另外还包括了一个额外的 ORM 特定子类 SQLORMExpression
。
参考:#8847
enum.IntFlag
类的使用,该类在 Python 3.11 中改变了其行为契约。这并没有导致运行时失败,但导致了在 Python 3.11 下的类型运行失败。
参考:#8783
sqlalchemy.ext.mutable
扩展和 sqlalchemy.ext.automap
扩展现在完全符合 pep-484 类型标准。非常感谢 Gleb Kisenkov 在这方面的努力。
参考:#6810, #8667
relationship.secondary
参数的类型支持,该参数也可以接受返回 FromClause
的可调用对象(lambda)。
sessionmaker
和 async_sessionmaker
的类型,使得它们的返回值的默认类型将会是 Session
或 AsyncSession
,而无需明确指定此类型。以前,Mypy 无法从其泛型基类自动推断出这些返回类型。
这次更改的一部分是,对于Session
、AsyncSession
、sessionmaker
和async_sessionmaker
的参数除了初始的“bind”参数之外,已经被设置为关键字参数,其中包括一直以来都被记录为关键字参数的参数,比如Session.autoflush
、Session.class_
等。
感谢 Sam Bull 提交的拉取请求。
参考:#8842
relationship.order_by
时在类型检查器中标记为错误的问题。
参考:#8776
Range.adjacent_to()
、Range.difference()
、Range.union()
等方法到 PG 特定的范围对象中,使其与底层 AbstractRange.comparator_factory
实现的标准操作保持一致。
此外,类的__bool__()
方法已校正,以与常见的 Python 容器行为以及其他流行的 PostgreSQL 驱动程序相一致:现在它告诉范围实例是否不为空,而不是相反。
拉取请求由 Lele Gaifax 提供。
参考:#8765
format
更改为numeric_dollar
。这有两个主要好处,因为它不需要对语句进行额外处理,并且允许语句中存在重复的参数。
参考:#8926
Range
类型进行了额外的类型检测,以前允许直接通过 DBAPI 接收 psycopg2 原生范围对象的情况已停止工作,因为现在我们有了自己的值对象。 Range
对象已得到增强,以便 SQLAlchemy 核心在其他模糊情况下检测到它(例如与日期的比较),并应用适当的绑定处理程序。拉取请求由 Lele Gaifax 提供。
参考:#8884
--disable-asyncio
参数的问题,该参数实际上无法禁止运行 greenlet 测试,并且也无法阻止套件在整个运行过程中使用“wrapping” greenlet。此参数现在确保在设置时不会在整个运行期间发生 greenlet 或 asyncio 使用。
此更改也反向移植到:1.4.44
参考:#8793
发布日期:2022 年 11 月 4 日
Select
构造的错误,其中Select.select_from()
与Select.join()
的组合,以及在使用Select.join_from()
时,会导致with_loader_criteria()
功能以及单表继承查询所需的 IN 条件在查询的列子句没有明确包含 JOIN 左侧实体时不会呈现。现在,正确的实体已传递给内部生成的Join
对象,以便正确添加对左侧实体的条件。
此更改也回溯到:1.4.43
参考:#8721
with_loader_criteria()
选项作为特定“加载器路径”添加的加载器选项时,现在会引发一个信息性异常,例如在Load.options()
中使用它时。这种用法不受支持,因为with_loader_criteria()
只打算用作顶级加载器选项。以前会生成内部错误。
此更改也回溯到:1.4.43
参考:#8711
Session.get()
改进了“字典模式”,以便可以在命名字典中指示引用主键属性名称的同义词名称。
此更改也回溯到:1.4.43
参考:#8753
Mapper.polymorphic_on
参数引用的 SQL 表达式不直接映射到类上。
此更改也回溯到:1.4.43
参考:#8704
Query
对象作为迭代器时,如果在迭代过程中出现用户定义的异常情况,则底层的 DBAPI 游标不会被关闭的问题。当使用Query.yield_per()
来创建服务器端游标时,这会导致通常与 MySQL 相关的服务器端游标不同步的问题,并且由于无法直接访问Result
对象,最终用户的代码无法访问游标以关闭它。
为了解决这个问题,在迭代器方法中应用了对GeneratorExit
的捕获,这样当迭代器被中断时将关闭结果对象,并且按定义将被 Python 解释器关闭。
作为针对 1.4 系列实现的这一变化的一部分,确保了在所有Result
实现上都提供了.close()
方法,包括ScalarResult
、MappingResult
。这一变化的 2.0 版本还包括了用于与Result
类一起使用的新上下文管理器模式。
这一变化也被回溯到了:1.4.43
参考:#8710
relationship()
指定的类名添加了支持,以及为Mapped
符号本身的名称,使其与直接的类名不同,以支持诸如将Mapped
导入为 from sqlalchemy.orm import Mapped as M
,或者相关类名以类似方式导入为替代名称的情况。此外,作为relationship()
的主参数给定的目标类名将始终优先于左手注释中给定的名称,以便仍然可以在注释中使用否则无法导入的名称,而且这些名称也不与类名匹配。
参考:#8759
Mapped[]
,通过确保 __allow_unmapped__
属性可以用于允许这些遗留注释通过 Annotated Declarative 而不引发错误,并且不在 ORM 运行时上下文中被解释。此外,当检测到这种情况时改进了生成的错误消息,并为应该如何处理这种情况添加了更多文档。不幸的是,1.4 WARN_SQLALCHEMY_20 迁移警告不能在运行时使用当前架构检测到这个特定的配置问题。
参考:#8692
Mapper
的一个基本配置行为,其中在 Mapper.properties
字典中显式存在的 Column
对象,无论是直接还是包含在映射器属性对象内部,现在都将在映射的 Table
(或其他可选择的)本身中以它们出现的顺序进行映射(假设它们实际上是该表的列列表的一部分),从而保持在映射的可选择上的列的顺序与在映射类中操纵的顺序相同,以及在 ORM SELECT 语句中为该映射器渲染的内容相同。以前(“以前”意味着自版本 0.0.1 以来),在 Mapper.properties
字典中的 Column
对象总是会首先映射,超过了在映射的 Table
中其他列的映射,导致在映射器分配属性给映射类时的顺序以及它们在语句中呈现的顺序之间存在差异。
此更改最显著地发生在声明式将声明的列分配给Mapper
的方式上,特别是在处理具有 DDL 名称明确不同于映射属性名称的Column
(或mapped_column()
)对象以及使用deferred()
等构造时。新行为将使映射的Table
中的列顺序与属性映射到类中的顺序相同,由Mapper
本身分配,并在 ORM 语句(如 SELECT 语句)中呈现,独立于Column
针对Mapper
的配置方式。
参考:#8705
ForwardRef
对象的解析器)中的问题,其中在一个特定的源文件中为列声明的类型在最终映射的类位于另一个源文件时会引发NameError
。现在,这些类型是根据每个类所在的模块来解析的。
参考:#8742
Result
和AsyncResult
对象的使用情况,现在这两个对象以及诸如ScalarResult
、MappingResult
、AsyncScalarResult
、AsyncMappingResult
等变体都支持上下文管理器的使用,结果将在上下文管理器块的末尾关闭。
另外,确保所有上述提到的Result
对象都包括Result.close()
方法以及Result.closed
访问器,包括以前没有.close()
方法的ScalarResult
和MappingResult
。
另请参阅
结果、AsyncResult 的上下文管理器支持
引用:#8710
PoolEvents.reset.reset_state
到PoolEvents.reset()
事件中,同时放置了一个将继续接受使用先前一组参数的事件钩子的弃用逻辑。这指示了关于重置正在进行的方式的各种状态信息,并且被用于允许在给定完整上下文的情况下进行自定义重置方案。
在这个改变中,也包括了一个在 1.4 中回溯的修复,该修复重新启用了PoolEvents.reset()
事件,以便在所有情况下继续进行,包括当Connection
已经“重置”连接时。
这两个更改共同允许使用PoolEvents.reset()
事件来实现自定义重置方案,而不是使用PoolEvents.checkin()
事件(其功能与以往一样)。
参考资料:#8717
Connection
关闭并且正在将其 DBAPI 连接返回到连接池时,在某些情况下不会调用PoolEvents.reset()
事件钩子。
当Connection
已经在将连接返回到池的过程中在其 DBAPI 连接上发出.rollback()
时,场景是它随后会指示连接池放弃执行自己的“重置”以节省额外的方法调用。但是,这会阻止在此钩子中使用自定义池重置方案,因为此类钩子根据定义正在执行的不仅仅是调用.rollback()
,而且需要在所有情况下调用。这是在版本 1.4 中出现的一种退化。
对于版本 1.4,PoolEvents.checkin()
仍然可作为用于自定义“重置”实现的备用事件钩子。版本 2.0 将提供一个改进版本的PoolEvents.reset()
,它将被调用用于额外的场景,例如终止 asyncio 连接,并且还传递有关重置的上下文信息,以允许对不同的重置方案作出响应以不同的方式处理不同的重置场景。
此更改也被回溯到:1.4.43
参考资料:#8717
literal_column()
构造在Select
构造的上下文中正常工作,以及其他可能生成“匿名标签”的地方,如果文字表达式包含可能干扰格式字符串的字符,例如括号,由于“匿名标签”的实现细节。
此更改也被回溯到:1.4.43
参考资料:#8724
Range.contains()
和 Range.contained_by()
到新的 Range
数据对象中,这些方法与 PostgreSQL 的 @>
和 <@
操作符的行为相同,以及 comparator_factory.contains()
和 comparator_factory.contained_by()
SQL 操作符方法。感谢 Lele Gaifax 提供的拉取请求。
参考:#8706
Inspector.has_table()
相关的问题,这会导致某些 Azure 变体上失败,因为不支持那些服务器版本上的一个不必要的信息模式查询。感谢 Mike Barry 提供的拉取请求。
此更改还回溯到:1.4.43
参考:#8714
Inspector.has_table()
相关的问题,当对使用 SQL Server 方言的视图使用时,错误地返回 False
,这是由于 1.4 系列中的一个回归导致的,该系列在 SQL Server 上删除了对此的支持。这个问题在使用不同反射架构的 2.0 系列中不存在。添加了测试支持,以确保 has_table()
符合视图的规范。
此更改还回溯到:1.4.43
参考:#8700
Optional[MyClass]
或类似形式(例如MyClass | None
)的类型注释的能力,导致错误。 文档还为这种用例添加了关于关系配置的文档。
此更改也回溯到:1.4.43
参考:#8744
发布日期:2022 年 10 月 20 日
Generic
子类的支持,可以在语句和调用inspect()
时指定为GenericAlias
对象(例如MyClass[str]
)。
参考:#8665
DeclarativeBase
类,以便与其他混入类(如MappedAsDataclass
)结合使用时,类的顺序可以是任意顺序。
参考:#8665
Optional[MyClass]
或类似形式(例如MyClass | None
)的类型注释的能力,导致错误。 文档还为这种用例添加了关于关系配置的文档。
参考:#8668
mapped_column()
声明的混入时,传递给 dataclasses API 的参数有时可能被错误排序,导致初始化问题。
参考:#8688
bindparam()
的子查询的 INSERT 在“insertmanyvalues”格式中无法正确呈现的问题。这直接影响了 psycopg2,因为“insertmanyvalues”在此驱动程序中无条件使用。
参考:#8639
__tablename__
、__mapper_args__
或__table_args__
时。
参考:#8645
mapped_column()
构造的类型问题。
参考:#8644
setinputsizes()
;对于 VARCHAR,如果字符大小大于 4000(或 2000,取决于数据),则会失败,因为传入的数据类型是 NVARCHAR,其限制为 4000 个字符,尽管 VARCHAR 可以处理无限字符。 当数据类型的大小> 2000 个字符时,现在还将传递额外的 pyodbc 特定的类型信息给setinputsizes()
。 这个更改也适用于受此问题影响的JSON
类型,用于大型 JSON 序列化。
参考:#8661
Sequence
构造恢复到了 1.4 系列之前的 DDL 行为,即创建一个没有额外参数的 Sequence
将会发出一个简单的 CREATE SEQUENCE
指令,没有任何额外的“起始值”参数。对于大多数后端来说,无论如何,这都是之前的工作方式;然而,对于 MS SQL Server,此数据库上的默认值是 -2**63
;为了防止这个通常不实用的默认值在 SQL Server 上生效,应该提供 Sequence.start
参数。由于对于多年以来一直在 IDENTITY
上标准化的 SQL Server 来说,对 Sequence
的使用是不寻常的,希望这个变化影响最小。
另请参阅
Sequence 构造不再具有任何显式默认的 “start” 值;影响 MS SQL Server
参考:#7211
发布日期:2022 年 10 月 13 日
Engine
和 Connection
现在使用新的 2.0 工作风格,其中包括 “autobegin”,库级别的自动提交已删除,子事务和 “branched” 连接已删除。
Row
完全是一个具有命名元组而没有 “映射” 行为,使用 RowMapping
来进行 “映射” 行为
convert_unicode
功能以及相关的在 DBAPI cursor.description
等中查找字节字符串的机制。
MetaData
,Table
和从以前可以引用 “绑定引擎”的所有 DDL/DML/DQL 元素中的 .bind
属性和参数
sqlalchemy.orm.mapper()
函数已移除;所有经典映射应通过registry.map_imperatively()
方法的registry
进行。
Query.join()
方法不再接受字符串作为关系名称;使用Class.attrname
作为连接目标的长期记录方法现在是标准的。
Query.join()
不再接受“aliased”和“from_joinpoint”参数。
Query.join()
不再在一个方法调用中接受多个连接目标链。
Query.from_self()
,Query.select_entity_from()
和Query.with_polymorphic()
已移除。
relationship.cascade_backrefs
参数现在必须保持其新默认值False
;save-update
级联不再沿着反向引用级联。
Session.future
参数必须始终设置为True
。 Session
的 2.0 风格事务模式现在始终生效。
Class.attrname
作为加载器选项目标的长期记录方法现在是标准的。
select()
已移除,包括select([cols])
,some_table.select()
的“whereclause”和关键参数。
Select
上的遗留“就地变异器”方法,如append_whereclause()
,append_order_by()
等已移除。
参考:#7257
Query.instances()
方法已弃用。该方法的行为约定,即可以通过任意结果集迭代对象,早已过时且不再测试。可以使用类似:meth.Select.from_statement
或aliased()
的构造来返回对象。
python setup.py build_ext
与以前一样工作,只需额外的 Cython 安装即可。pyproject.toml
现在也是源代码的一部分,当使用 pip 时将建立正确的构建依赖关系。
参见
C 扩展现已移植到 Cython
参考:#7256
pyproject.toml
文件,以完全支持 PEP 517。
参见
安装现在完全支持 pep-517
参考:#7311
AttributeEvents.include_key
,它将包含诸如 __setitem__()
(例如 obj[key] = value
)和 __delitem__()
(例如 del obj[key]
)等操作的字典或列表键,使用一个新的关键字参数“key”或“keys”,取决于事件,例如 AttributeEvents.append.key
,AttributeEvents.bulk_replace.keys
。这允许事件处理程序考虑传递给操作的键,对于与 MappedCollection
一起工作的字典操作尤其重要。
参考:#8375
Operators.op.python_impl
,可从Operators.op()
以及直接使用custom_op
构造函数时使用,允许提供一个在 Python 中进行评估的函数,以及自定义 SQL 运算符。当操作符对象在两侧使用普通 Python 对象作为操作数时,此评估函数将成为使用的实现,并且特别兼容与 ORM 启用的 INSERT、UPDATE 和 DELETE 语句一起使用的synchronize_session='evaluate'
选项。
参考:#3162
Session
(以及间接AsyncSession
)现在具有新的状态跟踪功能,将主动捕获在特定事务方法进行时发生的任何意外状态更改。这是为了允许在线程不安全的方式中使用Session
的情况,其中事件钩子或类似的可能在操作中调用意外方法,以及在其他并发情况下(如 asyncio 或 gevent)在首次发生非法访问时引发信息性消息,而不是默默传递导致由于Session
处于无效状态而导致的次要故障。
另请参阅
当检测到非法并发或重入访问时,会主动引发会话
参考:#7433
dataclass
一起使用时,composite()
映射构造现在支持值的自动解析;不再需要实现__composite_values__()
方法,因为此方法是从数据类的检查中派生的。
此外,由composite
映射的类现在支持排序比较操作,例如<
、>=
等。
请参阅复合列类型中的新文档以获取示例。
selectinload()
和immediateload()
加载器选项的非常实验性功能,名为selectinload.recursion_depth
/ immediateload.recursion_depth
,它允许单个加载器选项自动递归到自引用关系中。设置为指示深度的整数,并且也可以设置为-1,以指示继续加载直到找不到更多层级为止。对selectinload()
和immediateload()
进行了主要的内部更改,以便使此功能在继续正确使用编译缓存的同时工作,并且不使用任意递归,因此支持任何深度级别(尽管会发出相同数量的查询)。这对于必须完全急切加载的自引用结构可能会有用,例如在使用 asyncio 时。
当检测到相关对象加载中的过度递归深度时,还会发出警告,该警告也会在加载器选项以任意长度连接在一起时(即,不使用新的recursion_depth
选项)发出。此操作继续使用大量内存,并且性能极差;当检测到此条件时,缓存会被禁用,以防止缓存被任意语句淹没。
参考:#8126
Session.autobegin
,当设置为False
时,将阻止Session
隐式地开始事务。必须首先显式调用Session.begin()
方法,以便继续进行操作,否则在任何操作本应自动开始时都会引发错误。此选项可用于创建一个“安全”的Session
,该会话不会隐式启动新事务。
作为这一变化的一部分,还添加了一个新的状态变量 origin
,可能对事件处理代码有用,以了解特定 SessionTransaction
的来源。
参考:#6928
ForeignKey
引用的 Column
对象的声明性混合物不再需要使用 declared_attr()
来实现此映射;当列应用于声明的映射时,ForeignKey
对象与 Column
本身一起复制。
load_only()
加载器选项中添加了 load_only.raiseload
参数,以便未加载的属性可能具有“raise”行为而不是延迟加载。以前没有真正直接使用 load_only()
选项来实现这一点。
RelationshipProperty
成为主要名称 Relationship
的别名,始终由 relationship()
函数构建
SynonymProperty
成为主要名称 Synonym
的别名,始终由 synonym()
函数构建
CompositeProperty
现在成为主要名称Composite
的别名,始终由composite()
函数构建。
Mapped
保持一致,基于字典的集合attribute_mapped_collection()
、column_mapped_collection()
和MappedCollection
的名称已更改为attribute_keyed_dict()
、column_keyed_dict()
和KeyFuncDict
,使用“dict”短语以减少与术语“mapped”的混淆。旧名称将无限期保留,没有删除计划。
参考:#8608
Result
对象现在在硬关闭后使用时都会一致地引发ResourceClosedError
,包括在调用类似Result.first()
和Result.scalar()
这样的“单行或值”方法后发生的“硬关闭”。这已经是基于CursorResult
的最常见的 Core 语句执行返回的结果对象的行为,因此这种行为并不新鲜。然而,这一变化已经扩展到正确地适应使用 2.0 风格 ORM 查询时返回的 ORM“过滤”结果对象,以前这些对象会以“软关闭”方式返回空结果,或者根本不会真正“软关闭”并会继续从底层游标中产生结果。
作为这一变更的一部分,还将Result.close()
添加到基础Result
类中,并为 ORM 使用的过滤结果实现了它,这样就可以在使用yield_per
执行选项时调用底层CursorResult
上的CursorResult.close()
方法,在获取剩余的 ORM 结果之前关闭服务器端游标。这对于核心结果集已经可用,但此变更也使其适用于 2.0 风格的 ORM 结果。
此更改也回溯到:1.4.27
参考:#7274
registry.map_declaratively()
方法返回内部“映射器配置”对象而不是 API 文档中所述的Mapper
对象的问题。
defer()
的列,而不是已过期的未延迟列),将不会使用“优化”查询,该查询仅查询包含未加载列的直接表,而是运行完整的 ORM 查询,该查询会为所有基本表发出 JOIN,当仅从子类加载列时,这是不必要的。
参考:#7463
Load
对象及相关加载策略模式的内部大部分已经重写,以利用现在仅支持属性绑定路径而不是字符串的事实。重写希望能更直接地解决加载策略系统中的新用例和微妙问题。
参考:#6986
begin
和begin_nested
中删除了未使用的**kw
参数。这些 kw 没有被使用,似乎是错误地添加到 API 中的。
参考:#7703
attribute_mapped_collection()
和column_mapped_collection()
(现在称为attribute_keyed_dict()
和column_keyed_dict()
)在填充字典时使用的属性访问方法,断言对象上用作字典键的数据值实际上存在,并且不是因为属性从未被分配而使用“None”。这用于防止在通过反向引用进行分配时错误地为键分配 None,其中对象上的“键”属性尚未被分配。
由于此处的失败模式是一种通常不会持续到数据库的瞬态条件,并且很容易通过类的构造函数根据分配参数的顺序产生,因此很有可能许多应用程序已经包含了这种行为,而这种行为被悄悄地忽略了。为了适应现在引发此错误的应用程序,还添加了一个新参数 attribute_keyed_dict.ignore_unpopulated_attribute
到 attribute_keyed_dict()
和 column_keyed_dict()
,这个参数将导致错误的反向引用赋值被跳过。
参考:#8372
AbstractConcreteBase.strict_attrs
到 AbstractConcreteBase
声明混合类。这个参数的效果是,子类上的属性范围正确地限制在声明每个属性的子类中,而不是之前的行为,其中整个层次结构的所有属性都应用到基本的“抽象”类上。这样会产生更清晰、更正确的映射,子类不再具有仅对同级类有用的属性。此参数的默认值为 False,这保留了先前的行为不变;这是为了支持在查询中明确使用这些属性的现有代码。要迁移到更新的方法,根据需要将显式属性应用到抽象基类中。
参考:#8403
defer()
在处理主键和“多态鉴别器”列时的行为已经修订,以使这些列不再是可延迟的,无论是明确指定还是使用诸如 defer('*')
这样的通配符。先前,通配符延迟不会加载主键/多态列,这导致在所有情况下都出现错误,因为 ORM 依赖于这些列来生成对象标识。对主键列的显式延迟行为不变,因为这些延迟已经被隐式忽略。
参考:#7495
Mapper.eager_defaults
参数行为中的错误,使得仅在表定义中存在客户端 SQL 默认值或 onupdate 表达式时,ORM 为行执行 INSERT 或 UPDATE 时触发 RETURNING 或 SELECT 的操作。之前,仅服务器端默认值作为表 DDL 的一部分或服务器端 onupdate 表达式会触发此次提取,尽管客户端 SQL 表达式在渲染提取时也会被包含在内。
参考:#7438
DialectEvents.handle_error()
事件现已从 EngineEvents
套件移至 DialectEvents
套件,并且现在参与连接池的“预 ping”事件,对于那些使用断开代码来检测数据库是否存活的方言。这使得最终用户代码能够更改“预 ping”的状态。请注意,这不包括包含本地“ping”方法的方言,如 psycopg2 或大多数 MySQL 方言。
参考:#5648
ConnectionEvents.set_connection_execution_options()
和 ConnectionEvents.set_engine_execution_options()
事件钩子现在允许对给定的选项字典进行就地修改,新内容将作为最终执行选项接收。以前,不支持对字典进行就地修改。
create_engine.isolation_level
参数泛化到基本方言,因此不再依赖于单独的方言。该参数为所有新数据库连接的“隔离级别”设置提供了设置,一旦连接池创建它们,该值就会保持设置而不是在每次 checkin 时重置。
create_engine.isolation_level
参数在功能上与通过 Engine.execution_options.isolation_level
参数使用 Engine.execution_options()
设置相当。区别在于前者设置隔离级别只会在创建连接时执行一次,后者在每次连接检出时设置和重置给定级别。
参考:#6342
Dialect.set_isolation_level()
、Dialect.get_isolation_level()
、:meth: 方言方法将始终传递原始的 DBAPI 连接
Connection
和 Engine
类不再共享基础的 Connectable
超类,该超类已被移除。
PoolProxiedConnection
- 这是熟悉的_ConnectionFairy
类的公共接口,尽管它是一个私有类。
参考:#7122
CursorResult.fetchmany()
方法未能自动关闭服务器端游标(即在使用 stream_results
或 yield_per
时,无论是核心还是 ORM 导向的结果)的回归问题。
此更改也被回溯至:1.4.27
参考:#7274
Engine
中的问题,当调用 Engine.begin()
并进入上下文管理器时,如果实际的 BEGIN 操作由于某种原因失败,例如事件处理程序引发异常,则连接不会关闭;未来版本的引擎未测试此用例。请注意,“未来”上下文管理器在实际输入上下文管理器之前不会运行 “BEGIN” 操作。这与立即运行 “BEGIN” 操作的传统版本不同。
此更改也被回溯至:1.4.27
参考:#7272
pool_size=0
时,QueuePool
现在会忽略 max_overflow
,从而正确地使池在所有情况下都是无限的。
参考:#8523
str(url)
时,URL
对象现在默认使用密码混淆。要将 URL 字符串化为明文密码,可以使用 URL.render_as_string()
,将 URL.render_as_string.hide_password
参数传递为 False
。感谢我们的贡献者提供了此拉取请求。
另请参阅
str(engine.url) 现在默认混淆密码
参考:#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()
方法。
create_engine()
中移除了之前弃用的case_sensitive
参数,这只会影响 Core-only 结果集行中字符串列名称的查找;它不会影响 ORM 的行为。case_sensitive
指向的有效行为保持其默认值True
,意味着在row._mapping
中查找的字符串名称将与大小写敏感地匹配,就像任何其他 Python 映射一样。
请注意,case_sensitive
参数与控制大小写敏感性、引用和“名称规范化”(即转换为将所有大写字母视为大小写不敏感的数据库)DDL 标识符名称的一般主题没有任何关系,这仍然是 SQLAlchemy 的一个常规核心功能。
sqlalchemy.databases
。请改用sqlalchemy.dialects
。
引用:#7258
create_engine.implicit_returning
参数已经在create_engine()
函数中弃用;该参数仅在Table
对象上保留。该参数最初旨在在 SQLAlchemy 首次开发时启用“implicit returning”功能,但默认情况下未启用。在现代用法下,没有理由禁用该参数,并且观察到它会引起混乱,因为它会降低性能,使 ORM 更难以检索最近插入的服务器默认值。该参数仅在Table
上保留,以特别适应使 RETURNING 不可行的数据库级边缘情况,目前唯一的示例是 SQL Server 的限制,即不得在具有 INSERT 触发器的表上使用 INSERT RETURNING。
参考:#6962
ColumnOperators.icontains()
,ColumnOperators.istartswith()
,ColumnOperators.iendswith()
。这些操作符生成不区分大小写的 LIKE 组合(在 PostgreSQL 上使用 ILIKE,在所有其他后端上使用 LOWER()函数),以补充现有的 LIKE 组合操作符ColumnOperators.contains()
,ColumnOperators.startswith()
等。对于实现这些新方法的 Matias Martinez Rebori 的细致和完整的工作表示巨大的感谢。
参考:#3482
FromClause
对象的FromClause.c
集合中添加了新的语法,允许传递键的元组给__getitem__()
,以及支持select()
构造处理直接处理结果类似元组的集合,允许select(table.c['a', 'b', 'c'])
语法成为可能。返回的子集合本身也是一个ColumnCollection
,现在也可以直接被select()
和类似方法消耗。
参见
设置 COLUMNS 和 FROM 子句
参考:#8285
Uuid
数据类型,从 PostgreSQL 方言泛化到核心类型,以及将UUID
从 PostgreSQL 方言迁移到核心类型。SQL Server 的UNIQUEIDENTIFIER
数据类型也变成了一个 UUID 处理数据类型。感谢 Trevor Gross 的帮助。
参考:#7212
sqlalchemy.
模块命名空间添加了Double
、DOUBLE
、DOUBLE_PRECISION
数据类型,用于显式使用 double/double precision 以及通用的“double”数据类型。使用Double
来提供通用支持,根据不同后端需要解析为 DOUBLE/DOUBLE PRECISION/FLOAT。
参考:#5465
Insert
构造的编译机制,使得“自动递增主键”列值将通过 cursor.lastrowid
或 RETURNING 获取,即使它存在于参数集中或在 Insert.values()
方法中作为普通绑定值,用于特定后端上已知在明确传递 NULL 时仍生成自动递增值的单行 INSERT 语句。这恢复了 1.3 系列中的行为,用于分离的参数集以及 Insert.values()
方法。在 1.4 中,参数集行为无意中更改为不再执行此操作,但Insert.values()
方法仍会获取自动递增值,直到 1.4.21,其中 #6770 再次无意中更改了行为,因为此用例从未得到覆盖。
现在已定义行为为“工作”,以适应数据库(如 SQLite、MySQL 和 MariaDB 等)忽略显式 NULL 主键值并仍调用自动递增生成器的情况。
引用: #7998
literal_binds
一起使用时,添加了修改后的 ISO-8601 渲染(即将 T 转换为空格的 ISO-8601),对于 Oracle,ISO 格式被包装在适当的 TO_DATE() 函数调用内。先前,此渲染未针对方言特定编译实现。
另请参阅
DATE、TIME、DATETIME 数据类型现在在所有后端上支持文本渲染
引用: #5052
HasCTE.add_cte.nest_here
到 HasCTE.add_cte()
,该参数将在父语句级别“嵌套”给定的 CTE
。该参数等同于使用 HasCTE.cte.nesting
参数,但在某些情况下可能更直观,因为它允许同时设置嵌套属性和 CTE 的显式级别。
HasCTE.add_cte()
方法还接受多个 CTE 对象。
参考:#7759
Select.select_from()
方法在 select()
构造上建立 FROM 子句时,这些子句现在将首先在渲染的 SELECT 的 FROM 子句中呈现,这有助于保持子句的顺序,就像它们传递给 Select.select_from()
方法本身时一样,而不受这些子句也在查询的其他部分提及的影响。如果 Select
的其他元素也生成 FROM 子句,例如列子句或 WHERE 子句,这些将在由 Select.select_from()
提供的子句之后呈现,假设它们未明确传递给 Select.select_from()
。这一改进在某些情况下非常有用,其中特定数据库基于 FROM 子句的特定顺序生成理想的查询计划,并允许完全控制 FROM 子句的顺序。
参考:#7888
Enum.length
参数,用于为非本地枚举类型的 VARCHAR
列设置长度,在为 VARCHAR
数据类型发出 DDL 时现在无条件使用,包括当为目标后端设置了 Enum.native_enum
参数为 True
时继续使用 VARCHAR
的情况。在这种情况下,先前该参数将被错误地忽略。先前为此情况发出的警告现已移除。
参考:#7791
literal(25)
,现在也将应用基于值的适配,以适应 Python 大整数,其中确定的数据类型将是BigInteger
而不是Integer
。这适用于诸如 asyncpg 之类的方言,其既将隐式类型信息发送给驱动程序,又对数值刻度敏感。
参考:#7909
CreateSequence
、DropSequence
、CreateIndex
、DropIndex
等)添加了if_exists
和if_not_exists
参数,允许在 DDL 中呈现通用的“IF EXISTS”/“IF NOT EXISTS”短语。感谢 Jesse Bakker 提供的拉取请求。
参考:#7354
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
Integer
类型的两个表达式之间的“truediv”操作现在被视为Numeric
类型,并且方言级别的编译将根据方言特定的基础将右操作数转换为数字类型,以确保实现 truediv。对于 floordiv,还添加了转换,对于那些默认情况下不执行 floordiv 的数据库(如 MySQL、Oracle),在这种情况下还会渲染FLOOR()
函数,以及右操作数不是整数的情况(对于 PostgreSQL 等其他数据库也是需要的)。
此更改解决了不同后端上除法运算符行为不一致的问题,并修复了 Oracle 上整数除法无法获取结果的问题,因为输出类型处理程序不合适的问题。
另见
Python 除法运算符对所有后端执行真除法;添加了地板除法
参考:#4926
literal()
时,现在将应用 String
类型,而不是 Unicode
数据类型,对于使用 Python str.isascii()
测试为“ascii only”的 Python 字符串值。如果字符串不是 isascii()
,则将绑定 Unicode
数据类型,这在以前所有字符串检测中都使用了。这种行为仅适用于使用 literal()
或其他没有现有数据类型的上下文的数据类型的就地检测,通常不适用于正常的 Column
比较操作,其中正在比较的 Column
的类型始终优先。
在诸如 SQL Server 等后端中,使用Unicode
数据类型可以确定文字字符串的格式化方式,其中文字值(即使用 literal_binds
)将呈现为 N'<value>'
而不是 'value'
。对于常规绑定值处理,Unicode
数据类型还可能对传递值到 DBAPI 产生影响,再次以 SQL Server 为例,pyodbc 驱动程序支持使用 setinputsizes 模式,它将以不同方式处理 String
与 Unicode
。
参考:#7551
array_agg
现在将数组维度设置为 1。改进了对ARRAY
的处理,以接受None
值作为多维数组的值。
参考:#7083
ExecutableDDLElement
类(从 DDLElement
重命名)实现的“条件 DDL”系统上进行了扩展,直接可用于 SchemaItem
构造,如 Index
、ForeignKeyConstraint
等,使得用于生成这些元素的条件逻辑包含在默认的 DDL 发射过程中。这个系统也可以被 Alembic 的未来版本支持,以支持所有模式管理系统中的条件 DDL 元素。
另请参阅
新的条件 DDL 用于约束和索引
参考:#7631
DropConstraint
构造中添加了参数 DropConstraint.if_exists
,这将导致“IF EXISTS” DDL 被添加到 DROP 语句中。这个短语不被所有数据库接受,如果数据库不支持它,该操作将在一个单独的 DDL 语句的范围内失败,因为在这个范围内没有类似的兼容回退。感谢 Mike Fiedler 的拉取请求。
参考:#8141
SchemaItem
对象实现了 DDL 事件钩子 DDLEvents.before_create()
、DDLEvents.after_create()
、DDLEvents.before_drop()
、DDLEvents.after_drop()
,当该步骤被调用为一个独立的 SQL 语句时,包括 ForeignKeyConstraint
、Sequence
、Index
和 PostgreSQL 的 ENUM
。
参考:#8394
Inspector
对象的新 API 特性和行为改进,包括像Inspector.has_table()
、Inspector.get_table_names()
等方法的一致、缓存行为,以及新方法Inspector.has_schema()
和Inspector.has_index()
。
另见
数据库反射的主要架构、性能和 API 增强 - 完整背景
参考:#4379
Table.include_columns
参数排除后发现仍然是这些约束的一部分的列时,关于索引或唯一约束的反射发出的警告已被移除。当使用Table.include_columns
参数时,应该预期生成的Table
构造将不包括依赖于被省略列的约束。这个变化是对#8100作出的回应,该问题修复了Table.include_columns
与依赖于被省略列的外键约束的一起使用的情况,其中使用案例表明省略此类约束是可以预期的。
参考:#8102
Constraint
对象添加了对评论的支持,包括 DDL 和反射;该字段已添加到基本的Constraint
类和相应的构造函数中,但目前只有 PostgreSQL 是支持该功能的后端。请参阅参数,如ForeignKeyConstraint.comment
,UniqueConstraint.comment
或CheckConstraint.comment
。
参考:#5677
mysql_
或mariadb_
前缀。支持的选项包括:
stats_sample_pages
partition_by
partitions
subpartition_by
当从数据库加载表时,这些选项也会反映出来,并将填充表Table.dialect_options
。感谢 Ramon Will 的拉取请求。
参考:#4038
TypeEngine.with_variant()
方法现在返回原始TypeEngine
对象的副本,而不是将其包装在Variant
类中,该类实际上已被移除(导入符号仍保留以向后兼容可能测试此符号的代码)。虽然以前的方法保持了 Python 中的行为,但保持原始类型允许更清晰的类型检查和调试。
TypeEngine.with_variant()
还可以在每次调用时接受多个方言名称,特别是对于相关的后端名称,如"mysql", "mariadb"
。
另请参阅
“with_variant()”克隆原始 TypeEngine 而不是更改类型
参考:#6980
DOMAIN
数据类型,其遵循与 PostgreSQL ENUM
相同的 CREATE TYPE / DROP TYPE 行为。非常感谢 David Baumgold 的努力。
另见
DOMAIN
参考:#7316
PGDialect_asyncpg.setup_asyncpg_json_codec
和 PGDialect_asyncpg.setup_asyncpg_jsonb_codec
,用于在使用 asyncpg 时注册这些数据类型所需的 JSON/JSONB 编解码器。变更之处在于将方法拆分为单独的可重写方法,以支持需要修改或禁用这些特定编解码器设置的第三方方言。
此变更还被 回溯 到:1.4.27
参考:#7284
ARRAY
和 ARRAY
数据类型添加了文字类型渲染。通用的字符串化将使用方括号进行渲染,例如 [1, 2, 3]
,而 PostgreSQL 特定的将使用 ARRAY 文字,例如 ARRAY[1, 2, 3]
。还考虑了多维和引号。
参考:#8138
Range
数据对象。请参阅新文档以了解使用模式。
此外,增强了范围类型处理,以便自动渲染类型转换,因此对于不提供任何上下文的语句的就地往返,不需要为数据库明确指定所需的类型(在 #8540 中讨论)。
非常感谢 @zeeeeeb 提交并测试新数据类型和 psycopg 支持的拉取请求。
另见
PostgreSQL 后端的新 RANGE / MULTIRANGE 支持和变更
范围和多范围类型
参考:#7156, #8540
create_engine.pool_pre_ping
时发出的“ping”查询,对于 psycopg、asyncpg 和 pg8000,但不适用于 psycopg2,已更改为一个空查询(;
),而不是SELECT 1
;此外,对于 asyncpg 驱动程序,已修复了此查询不必要使用准备语句的问题。其理由是消除 PostgreSQL 在发出 ping 时产生查询计划的需要。当前不支持由psycopg2
驱动程序执行此操作,它继续使用SELECT 1
。
参考:#8491
UUID
的参数UUID.as_uuid
,以前专门针对 PostgreSQL 方言,现在已经泛化为 Core(连同一个新的与后端无关的Uuid
数据类型),现在默认为True
,表示此数据类型默认接受 Python UUID
对象。此外,SQL Server 的UNIQUEIDENTIFIER
数据类型已转换为接收 UUID 的类型;对于使用字符串值的遗留代码,设置UNIQUEIDENTIFIER.as_uuid
参数为False
。
参考:#7225
ENUM
数据类型的ENUM.name
参数现在是一个必需的关键字参数。在任何情况下,“name”都是必要的,否则在 SQL/DDL 渲染时会引发错误。
setinputsizes()
方法,或者对于 psycopg2 驱动程序,在大多数情况下将依赖于驱动程序本身,对于 ARRAY 则会做一些特殊的例外。
现在,所有 PostgreSQL 方言都使用 PostgreSQL 双冒号样式在编译器内呈现这些转换所需的转换,并且对于 PostgreSQL 方言,已删除了使用setinputsizes()
,因为这在任何情况���通常不是这些 DBAPI 的一部分(pg8000 是唯一的例外,它在 SQLAlchemy 开发人员的请求下添加了该方法)。
这种方法的优势包括每个语句的性能,因为在执行时不需要对编译后的语句进行第二次遍历,对所有 DBAPI 的更好支持,因为现在有一个一致的应用类型信息系统,以及改进的透明度,因为 SQL 日志输出以及编译语句的字符串输出将直接显示这些转换存在于语句中,而以前这些转换在日志输出中是不可见的,因为它们会在语句记录后发生。
Operators.match()
运算符现在在 PostgreSQL 全文搜索中使用plainto_tsquery()
,而不是to_tsquery()
。这种更改的理由是为了提供更好的与其他数据库后端上的 match 的跨兼容性。通过与Operators.bool_op()
(布尔运算符的改进版本Operators.op()
)结合使用func
,仍然可以通过使用所有 PostgreSQL 全文函数来获得完全支持。
另请参阅
PostgreSQL 上的 match()运算符使用 plainto_tsquery()而不是 to_tsquery()
参考:#7086
github.com/PyGreSQL
获得。请切换到受支持的驱动程序之一或同一驱动程序的外部版本。 参考:#7258
psycopg
方言的支持,支持同步和异步执行。此方言在 create_engine()
和 create_async_engine()
引擎创建函数下可用。
另请参阅
对 psycopg 3(又名“psycopg”)的方言支持
psycopg
参考:#6842
JSONPATH
,可在转换表达式中使用。在使用诸如 jsonb_path_exists
或 jsonb_path_match
这样接受 jsonpath
作为输入的函数时,某些 PostgreSQL 方言需要这个类型。
另请参阅
JSON 类型 - PostgreSQL JSON 类型。
参考:#8216
Inspector.get_indexes()
时以及使用 Table.autoload_with
反射 Table
时都支持反射。感谢 immerrr 和 Aidan Kane 在这个问题上的帮助。
参考:#7442
ROLLUP
函数现在会在 MySql 和 MariaDB 上正确呈现 WITH ROLLUP
,允许在这些后端使用 group by rollup。
参考:#8503
Insert.on_duplicate_key_update()
中的问题,当在 VALUES 表达式中使用表达式时,会呈现错误的列名。感谢 Cristian Sabaila 提供的拉取请求。
此更改也 被后移 到:1.4.27
参考:#7281
is_delete_using=True
,当使用 ORM 启用的 DELETE 语句与“fetch”同步策略一起使用时,该选项将被消耗;此选项表示预计 DELETE 语句将使用多个表,在 MariaDB 上是 DELETE…USING 语法。然后,该选项指示对于已知不支持“DELETE…USING…RETURNING”语法的数据库,不应使用在 MariaDB 中新实现的 SQLAlchemy 2.0 的 RETURNING(对于#7011)。尽管它们支持“DELETE…USING”,但它们不支持“DELETE…USING…RETURNING”语法,这是 MariaDB 的当前能力。
这个选项的原因是,ORM 启用的 DELETE 当前不知道 DELETE 语句是否针对多个表,直到编译发生,无论如何,编译都会被缓存,但需要知道这一点,以便事先发出用于待删除行的 SELECT。与为了预先检查所有 DELETE 语句以获取这种相对不寻常的 SQL 模式而对所有 DELETE 语句应用全面性能惩罚相比,通过在编译步骤中引发一个新的异常消息来请求is_delete_using=True
执行选项。此异常消息仅在以下情况下特定(且仅)引发:语句是启用了 ORM 的 DELETE,已请求“fetch”同步策略;后端是 MariaDB 或具有此特定限制的其他后端;已检测到初始编译中的语句,否则会发出“DELETE…USING…RETURNING”。通过应用执行选项,ORM 知道要首先运行一个 SELECT。ORM 启用的 UPDATE 也实现了类似的选项,但目前还没有需要它的后端。
参考:#8344
sqlite_include_internal=True
的新参数;当省略时,以sqlite_
为前缀的本地表(根据 SQLite 文档,这些表被称为“内部模式”表,例如生成以支持“AUTOINCREMENT”列的sqlite_sequence
表),不会包含在返回本地对象列表的反射方法中。这样可以避免在使用 Alembic 自动生成时出现问题,以前会将这些由 SQLite 生成的表视为从模型中移除。
另请参阅
反射内部模式表
参考:#8234
Update
构造时,当使用多个表或其他实体或可选择时,此语法会自动调用。
参考:#7185
QueuePool
。这是与将check_same_thread
参数设置为False
一起设置的。已经观察到,默认使用NullPool
的先前方法,在释放数据库连接后不会保留连接,实际上会对性能产生可衡量的负面影响。如常,通过create_engine.poolclass
参数可以自定义池类。
参见
SQLite 方言为基于文件的数据库使用 QueuePool
参考:#7490
fromisoformat()
方法来解析传入的 datetime、date 和 time 字符串值。这比以前基于正则表达式的方法提高了性能,还自动适应包含六位“微秒”格式或三位“毫秒”格式的 datetime 和 time 格式。
参考:#7029
Numeric
类型发出的关于 DBAPI 不原生支持 Decimal 值的警告。这个警告是针对 SQLite 的,因为 SQLite 没有任何真正的方法(除非使用额外的扩展或解决方法)来处理超过 15 个有效数字的精度数值,因为它只使用浮点数来表示数字。由于这是 SQLite 本身已知且有文档记录的限制,而不是 pysqlite 驱动程序的怪癖,因此 SQLAlchemy 不需要为此发出警告。这个更改不会修改精度数值的处理方式。值可以继续按照 Numeric
、Float
和相关数据类型配置为 Decimal()
或 float()
,只是在使用 SQLite 时无法保持超过 15 个有效数字的精度,除非使用字符串等替代表示方法。
参考:#7299
mssql_clustered
的反射。感谢 John Lennox 提供的拉取请求。
参考:#8288
mssql+pyodbc
方言的 use_setinputsizes
参数现在默认为 True
;这样非 Unicode 字符串比较将由 pyodbc 绑定到 pyodbc.SQL_VARCHAR 而不是 pyodbc.SQL_WVARCHAR,从而使得对 VARCHAR 列的索引生效。为了让 fast_executemany=True
参数继续正常工作,use_setinputsizes
模式现在在 fast_executemany
为 True 且使用的具体方法是 cursor.executemany()
时会跳过 cursor.setinputsizes()
调用,因为该方法不支持 setinputsizes。此更改还为被标记为 Unicode
或 UnicodeText
的值添加了适当的 pyodbc DBAPI 类型,并将基础的 JSON
数据类型修改为将 JSON 字符串值视为 Unicode
而不是 String
。
参考:#8177
oracledb
的支持。
另请参阅
对 oracledb 的方言支持
python-oracledb
参考:#8054
FLOAT
数据类型的 DDL 和反射支持,其中包括显式的“binary_precision”值。使用特定于 Oracle 的 FLOAT
数据类型,可以指定新参数 FLOAT.binary_precision
,这将直接呈现 Oracle 的浮点类型精度。此值在反射期间解释。在反射回 FLOAT
数据类型时,返回的数据类型是 DOUBLE_PRECISION
(对于精度为 126 的 FLOAT
,这也是 Oracle 的默认精度)、REAL
(对于精度为 63)、以及 FLOAT
(对于自定义精度,按照 Oracle 文档)。
作为这一变更的一部分,当为 Oracle 生成 DDL 时,明确拒绝了通用的 Float.precision
值,因为此精度无法准确转换为“二进制精度”;相反,错误消息鼓励使用 TypeEngine.with_variant()
,以便精确选择 Oracle 的特定精度形式。这是一种与以往行为不兼容的更改,因为以前的“精度”值对于 Oracle 被静默地忽略。
另请参阅
新的 Oracle FLOAT 类型,具有二进制精度;不直接接受十进制精度
参考:#5465
cursor.executemany()
时,RETURNING 每个语句产生一行。这一特性的实现为 ORM 插入提供了显著的性能改进,就像 SQLAlchemy 1.4 变更 ORM Batch inserts with psycopg2 now batch statements with RETURNING in most cases 中为 psycopg2 添加的一样。
参考:#6245
Select.fetch()
时,该语法已经可用,现在对 Select.limit()
和 Select.offset()
也适用。
参考:#8221
MetaData.reflect()
反映,除非设置了 views=True
。要获取物化视图列表,请使用新的检查方法 Inspector.get_materialized_view_names()
。
create_engine.implicit_returning
弃用的相关内容,现在 “implicit_returning” 特性在所有情况下都为 Oracle 方言启用;以前,当检测到 Oracle 8/8i 版本时,该特性会被关闭,然而在线文档显示这两个版本都支持与现代版本相同的 RETURNING 语法。
参考:#6962
无发布日期
ORMExecuteState.is_from_statement
,用于检测形式为select().from_statement()
的语句,并增强了FromStatement
以根据发送到Select.from_statement()
方法本身的元素设置ORMExecuteState.is_select
、ORMExecuteState.is_insert
、ORMExecuteState.is_update
和ORMExecuteState.is_delete
。
参考:#11220
Connection.execution_options.logging_token
选项中的问题,其中更改已经记录了消息的连接的logging_token
值不会更新以反映新的记录令牌。特别是这阻止了使用Session.connection()
在连接上更改选项,因为 BEGIN 记录消息已经被发出。
参考:#11210
ParamSpec
添加到 asyncio run_sync()
方法中,其中使用AsyncConnection.run_sync()
与MetaData.reflect()
将由于 bug 在 mypy 上失败。有关详细信息,请参见github.com/python/mypy/issues/17093
。Pull request 由 Francisco R. Del Roio 提供。
参考:#11200
subprocess.run
时,请确保PYTHONPATH
变量正确初始化。
参考:#11268
ORMExecuteState.is_from_statement
,用于检测形式为select().from_statement()
的语句,并增强了FromStatement
以根据发送到Select.from_statement()
方法本身的元素设置ORMExecuteState.is_select
、ORMExecuteState.is_insert
、ORMExecuteState.is_update
和ORMExecuteState.is_delete
。
参考:#11220
Connection.execution_options.logging_token
选项中的问题,其中在已经记录了消息的连接上更改logging_token
的值不会更新以反映新的日志令牌。特别是这阻止了使用Session.connection()
在连接上更改选项,因为 BEGIN 日志消息已经被发出。
参考:#11210
ParamSpec
添加到 asyncio run_sync()
方法中,其中在 mypy 上使用AsyncConnection.run_sync()
与MetaData.reflect()
会由于错误而在 mypy 上失败。有关详细信息,请参见github.com/python/mypy/issues/17093
。感谢 Francisco R. Del Roio 提供的拉取请求。
参考:#11200
subprocess.run
时,请确保PYTHONPATH
变量正确初始化。
参考:#11268
发布日期:2024 年 3 月 23 日
TypeAliasType
构造的支持,以及与 python 3.12 本地 type
关键字配合使用 ORM 注释声明形式时,当使用这些构造将链接到 PEP 593 Annotated
容器时,允许解析Annotated
的过程。
参考文献:#11130
Relationship
而不是 Mapped
来对关系进行类型化,会无意中为该属性引入“动态”关系加载器策略。
参考文献:#10611
mapped_column()
时出现的问题,其中使用mapped_column.index
或mapped_column.unique
设置为False
的情况将被一个具有该参数设置为True
的传入Annotated
元素覆盖,即使直接mapped_column()
元素更具体且应该优先。增强了协调布尔值的逻辑,以适应本地值为False
仍优先于来自注释元素的传入True
值的情况。
参考文献:#11091
subqueryload()
加载器选项的实现,当使用此加载器选项与此加载器选项一起使用时,会使用一些更多的旧模式。
参考文献:#11173
Sequence
和显式架构名称,同时使用Connection.execution_options.schema_translate_map
功能将无法正确呈现序列或参数,导致错误。
参考:#11157
TypeEngine.with_variant()
方法的重构中引入的问题,该方法在 “with_variant()” 克隆原始 TypeEngine 而不是更改类型 中未能考虑到 .copy()
方法,这将丢失设置的变体映射。对于“schema”类型的非常特定情况,这会成为一个问题,其中包括 Enum
和 ARRAY
等类型,当它们在 ORM Declarative 映射中与 mixin 一起使用时,类型的复制就会发挥作用。现在也复制了变体映射。
参考:#11176
run_sync()
方法正确对参数进行类型标记的问题,根据传递的可调用对象使用 PEP 612 ParamSpec
变量。感谢 Francisco R. Del Roio 提供的拉取请求。
参考:#11055
DOMAIN
实例。之前,返回的是域数据类型。作为此更改的一部分,改进了域反射以同时返回文本类型的排序规则。感谢 Thomas Stephenson 提供的拉取请求。
参考:#10693
asyncio.Runner
或其等价物,而不是依赖于先前基于 asyncio.get_running_loop()
的实现。这应该能够在 CPU 负载硬件上运行大量套件时防止事件循环出现故障,导致级联失败。
参考:#11187
TypeAliasType
构造的支持,以及与 Python 3.12 本地 type
关键字一起使用 ORM Annotated Declarative 形式时的支持,当使用这些构造链接到 PEP 593 Annotated
容器时,允许解析 Annotated
时继续进行。
参考:#11130
Relationship
而不是 Mapped
来定义关系会无意中引入该属性的“动态”关系加载器策略。
引用:#10611
mapped_column.index
或 mapped_column.unique
设置为 False 的 mapped_column()
会被传入的 Annotated
元素覆盖,即使直接的 mapped_column()
元素更具体且应该优先。调解布尔值的逻辑已经得到增强,以适应本地值为 False
的情况,仍然优先于注释元素传入的 True
值。
引用:#11091
subqueryload()
加载器选项的实现,当使用额外的加载器条件特性与此加载器选项一起使用时,内部使用了一些更传统的模式。
引用:#11173
Sequence
并带有显式模式名称),同时使用 Connection.execution_options.schema_translate_map
功能将无法正确渲染序列或参数,导致错误。
引用:#11157
TypeEngine.with_variant()
方法的重构,引入了“with_variant()”克隆原始 TypeEngine 而不是更改类型,未能适应 .copy()
方法,这将丢失设置的变体映射。对于非常特定的“模式”类型,这成为问题,该类型包括在 ORM Declarative 映射中与混合使用时的类型,其中类型的复制变得重要。现在也复制了变体映射。
参考:#11176
run_sync()
方法正确对参数进行类型标记的输入问题,根据传递的可调用对象,使用了PEP 612 ParamSpec
变量。感谢 Francisco R. Del Roio 提交的拉取请求。
参考:#11055
DOMAIN
实例。以前,会返回域数据类型。作为这一改变的一部分,域反射还改进了以返回文本类型的排序规则。感谢 Thomas Stephenson 提交的拉取请求。
参考:#10693
asyncio.Runner
或等价的后移版,而不是依赖于基于 asyncio.get_running_loop()
的先前实现。这样做希望能够防止在 CPU 负载硬件上运行大量测试时出现问题,其中事件循环似乎会变得损坏,导致级联故障。
参考:#11187
发布日期:2024 年 3 月 4 日
with_expression()
构造中使用的缓存键生成过程中可能变化的绑定参数值。新逻辑改变了将新绑定参数值与语句关联的方法,避免了需要深度复制语句的情况,这可能会对非常深/复杂的 SQL 构造造成显著的性能损耗。新方法不再需要这个深复制步骤。
参考:#11085
and_()
表达式中使用“secondary”表会失败,无法将其别名为与 Select.join()
表达式中“secondary”表的正常渲染相匹配,导致查询无效。
参考:#11010
Connection.execution_options.preserve_rowcount
。设置后,DBAPI 游标的cursor.rowcount
属性将在语句执行时无条件地被记忆化,因此无论 DBAPI 为任何类型的语句提供的值是什么,都可以使用CursorResult.rowcount
属性从CursorResult
中获取。这允许访问像 INSERT 和 SELECT 这样的语句的 rowcount,程度取决于所使用的 DBAPI 的支持。INSERT
语句的“插入多个值”行为也支持此选项,并在设置时将确保为批量插入行时正确设置CursorResult.rowcount
。
参考:#10974
QueuePool
或其他非异步池类传递给create_async_engine()
,则会引发错误。此引擎仅接受包括AsyncAdaptedQueuePool
在内的符合 asyncio 的池类。其他池类,如NullPool
,与同步和异步引擎兼容,因为它们不执行任何锁定。
另请参阅
API 文档 - 可用的池实现
参考:#8771
with_expression()
构造中使用的缓存键生成过程中可能更改的绑定参数值。新逻辑改变了将新绑定参数值与语句关联的方法,避免了需要深度复制语句的需求,这可能会对非常深/复杂的 SQL 结构造成显著的性能损耗。新方法不再需要这个深度复制步骤。
参考:#11085
and_()
表达式中使用 “secondary” 表会无法被别名化,以匹配 “secondary” 表在 Select.join()
表达式中通常的呈现方式,导致查询无效。
参考:#11010
Connection.execution_options.preserve_rowcount
。当设置时,DBAPI 游标的 cursor.rowcount
属性将在语句执行时无条件地被存储,以便无论语句的任何种类,都可以使用 CursorResult.rowcount
属性从 CursorResult
获取 DBAPI 提供的任何值。这允许访问像 INSERT 和 SELECT 这样的语句的 rowcount,以 DBAPI 使用的程度支持。“INSERT 语句的插入多个值”行为 也支持此选项,并将确保在设置时对行进行批量插入时正确设置 CursorResult.rowcount
。
参考:#10974
QueuePool
或其他非 asyncio 连接池类传递给 create_async_engine()
,则会引发错误。此引擎仅接受与 asyncio 兼容的连接池类,包括 AsyncAdaptedQueuePool
。其他连接池类,如 NullPool
,与同步和异步引擎均兼容,因为它们不执行任何锁定。
另请参见
API 文档 - 可用的连接池实现
参考:#8771
发布日期:2024 年 2 月 13 日
发布日期:2024 年 2 月 11 日
Mapped
容器类型中使用类型(例如枚举)。现在,用于评估的本地变量范围包括类体本身的范围。此外,如果以字符串形式或使用将来的注释模式,Mapped
中的表达式也可以引用类名本身。
参考:#10899
Session.delete()
与 Mapper.version_id_col
功能时,如果由于对象上的 relationship.post_update
的使用导致针对目标对象的附加 UPDATE,则使用正确的版本标识符将失败。这个问题类似于版本 2.0.25 中刚刚修复的 #10800 的情况,仅对更新情况进行了修复。
参考:#10967
with_expression()
时,如果使用不可缓存的 SQL 表达式,则会引发断言错误的问题;这是自 1.4 以来的 2.0 回归。
参考:#10990
MetaData.to_metadata()
复制历史表时也会复制索引(这是一件好事),但无论用于这些索引的命名方案如何,都会导致索引命名冲突。现在这些索引都添加了“_history”后缀,方式与表名相同。
参考:#10920
Identity
构造,并允许在此后端上进行主键生成,修复了 examples/performance 中性能示例脚本在 Oracle 数据库中大部分情况下的运行问题。仍有一些“原始 DBAPI”情况与 Oracle 不兼容。
case()
中确定表达式类型的逻辑问题,可能导致如果“whens”中的最后一个元素没有类型,则结果为NullType
,或者在其他情况下,类型可能解析为None
。逻辑已更新为扫描所有给定表达式,以便使用第一个非空类型,并始终确保存在类型。拉取请求由 David Evans 提供。
参考:#10843
PoolEvents.checkin()
事件的类型签名,指示给定的DBAPIConnection
参数在连接被无效化的情况下可能为None
。
no_inherit=True
。拉取请求由 Ellis Valentiner 提供。
参考:#10777
CREATE TABLE
的 USING <method>
选项,以指定用于存储新表内容的访问方法。拉取请求由 Edgar Ramírez-Mondragón 提供。
另请参阅
PostgreSQL 表选项
参考:#10904
Range[T]
和 Sequence[Range[T]]
。引入了实用序列 MultiRange
,以便更好地支持 MULTIRANGE 类型的互操作性。
参考:#9736
Range
或 MultiRange
实例推断数据库类型时,区分 INT4 和 INT8 范围和多范围类型,如果值适合 INT4,则优先选择 INT4。
terminate()
,没有考虑到优雅的 .close()
尝试由于其他原因(如连接错误)失败的情况。
参考:#10863
Uuid
数据类型且将 Uuid.as_uuid
参数设置为 False 时出现的问题,ORM 优化的 INSERT 语句(例如“insertmanyvalues”功能)将无法正确对齐批量 INSERT 语句的主键 UUID 值,导致错误。类似的问题也已经为 pymssql 驱动程序修复。
.close()
方法显然不是一个优雅的关闭。替换为非标准的 .ensure_closed()
方法,该方法是可等待的,并将 .close()
移动到所谓的“终止”情况。
参考:#10893
Uuid
数据类型且Uuid.as_uuid
参数设置为 False 时的问题。ORM 优化的 INSERT 语句(例如“insertmanyvalues”功能)将无法正确对齐用于批量 INSERT 语句的主键 UUID 值,导致错误。类似的问题也已针对 PostgreSQL 驱动程序进行了修复。
Mapped
容器类型中使用该类型的问题。现在,用于 eval 的本地变量范围包括类体本身。此外,Mapped
中的表达式也可以引用类名本身,如果作为字符串或使用未来注释模式。
参考:#10899
Session.delete()
与Mapper.version_id_col
功能一起时,如果由于对象上的relationship.post_update
的使用导致针对目标对象发出额外的 UPDATE,则会失败使用正确的版本标识符的问题。该问题类似于#10800,只是在仅有更新的情况下在版本 2.0.25 中修复了。
参考:#10967
with_expression()
实现中,如果使用的 SQL 表达式不可缓存,则会引发断言错误的问题;这是自 1.4 版以来的 2.0 版本的退化。
参考:#10990
MetaData.to_metadata()
来复制历史表也会复制索引(这是好事),但无论使用的索引命名方案如何,都会导致索引命名冲突。现在为这些索引添加了“_history”后缀,方式与为表名添加后缀相同。
参考:#10920
Identity
结构并允许主键在此后端上生成,修复了 examples/performance 中性能示例脚本在 Oracle 数据库中的大部分兼容性问题。一些“原始 DBAPI” 情况仍不兼容 Oracle。
case()
中确定表达式类型的逻辑问题,如果“whens”中的最后一个元素没有类型或在其他情况下类型可能解析为 None
,则可能导致 NullType
。逻辑已更新以扫描所有给定表达式,以使用第一个非空类型,并始终确保存在类型。感谢 David Evans 提交的拉取请求。
参考:#10843
PoolEvents.checkin()
事件的类型签名,指示给定的 DBAPIConnection
参数在连接被失效的情况下可能为 None
。
no_inherit=True
。感谢 Ellis Valentiner 提交的拉取请求。
参考:#10777
CREATE TABLE
中的 USING <method>
选项,以指定用于存储新表内容的访问方法。感谢 Edgar Ramírez-Mondragón 提交的拉取请求。
另请参阅
PostgreSQL 表选项
参考:#10904
Range[T]
和Sequence[Range[T]]
。引入了实用程序序列MultiRange
,以更好地支持 MULTIRANGE 类型的互操作性。
参考:#9736
Range
或MultiRange
实例推断数据库类型时,区分 INT4 和 INT8 范围和多范围类型,如果值适合 INT4,则优先使用 INT4。
terminate()
,没有考虑到当优雅的.close()
尝试由于其他原因(如连接错误)失败时的情况。
参考:#10863
Uuid
数据类型且Uuid.as_uuid
参数设置为 False 时的问题。ORM 优化的 INSERT 语句(例如“insertmanyvalues”功能)不会正确对齐批量 INSERT 语句的主键 UUID 值,导致错误。pymssql 驱动程序也修复了类似的问题。
.close()
方法显然不是一个优雅的关闭。将其替换为非标准的.ensure_closed()
方法,该方法可等待,并将.close()
移到所谓的“终止”情况。
参考:#10893
Uuid
数据类型以及设置Uuid.as_uuid
参数为 False 时的问题,当使用 pymssql 方言时,ORM 优化的 INSERT 语句(例如“insertmanyvalues”功能)将不正确地对齐批量 INSERT 语句的主键 UUID 值,导致错误。类似的问题也已在 PostgreSQL 驱动程序中修复。
发布日期:2024 年 1 月 2 日
relationship.post_update
特性和使用映射器 version_id_col 时可能导致第二个 UPDATE 语句未能使用正确的版本标识符的问题,假设在该 flush 中已经发出了一个已经增加了版本计数器的 UPDATE。
参考:#10800
any_()
/ all_()
的编译,现在将呈现NOT (expr)
而不是将等式操作符反转为不等号,允许对这些非典型操作符进行更精细的否定控制。
参考:#10817
sqlalchemy.sql.functions
模块添加了类型后引起的回归问题,作为#6810的一部分:
AsyncEngine.dispose()
会生成一个新的连接池,该连接池未完全重新建立对 asyncio 兼容互斥锁的使用,导致在使用像 asyncio.gather()
这样的并发特性时,在 asyncio 上下文中发生死锁时使用了普通的 threading.Lock()
。
此更改也 回溯 到:1.4.51
引用:#10813
oracledb
DBAPI 版本。 对于 2.0 系列,这是一个预览版本,当前实现尚未包括对 AsyncConnection.stream()
的支持。 改进的支持计划在 SQLAlchemy 的 2.1 发布中实现。
引用:#10679
relationship.post_update
功能和使用 mapper version_id_col 时可能导致的问题,在这种情况下,后续更新功能发出的第二个 UPDATE 语句可能无法使用正确的版本标识符,假设在该刷新中已经发出了一个已经增加了版本计数器的 UPDATE。
引用:#10800
any_()
/ all_()
的编译,现在将呈现NOT (expr)
而不是将等式运算符反转为不等于,允许更精细地控制这些非典型运算符的否定。
参考:#10817
sqlalchemy.sql.functions
模块的类型提示引起的回归,作为#6810的一部分:
AsyncEngine.dispose()
会产生一个未完全重新建立使用 asyncio 兼容互斥锁的新连接池,导致在使用并发功能时(如asyncio.gather()
)在 asyncio 上下文中使用普通的threading.Lock()
会导致死锁。
此更改也回溯到:1.4.51
参考:#10813
oracledb
DBAPI。对于 2.0 系列,这是一个预览版本,当前实现尚未包括对AsyncConnection.stream()
的支持。改进的支持计划在 SQLAlchemy 的 2.1 版本中实现。
参考:#10679
发布日期:2023 年 12 月 28 日
mapped_column()
构造上使用foreign()
注释会产生一个没有类型的表达式的问题,然后在实际列初始化时未更新,导致关系未适当确定use_get
的问题。
参考:#10597
MappedAsDataclass
、DeclarativeBase
和DeclarativeBaseNoMeta
使用的__init_subclass__()
方法,以接受任意的**kw
并将其传播到super()
调用,允许更大的灵活性安排使用__init_subclass__()
关键字参数的自定义超类和混入。拉取请求由 Michael Oliver 提供。
参考:#10732
returning()
部分中使用的Bundle
对象的用例经过测试并完全可用。这在以前从未明确实现或测试过,并且在 1.4 系列中无法正常工作;在 2.0 系列中,带有 WHERE 条件的 ORM UPDATE/DELETE 缺少实现方法,导致无法使用Bundle
对象。
参考:#10776
MutableList
的回归问题,其中检测序列的例程未能正确过滤字符串或字节实例,导致无法将字符串值分配给特定索引(而非序列值将正常工作)。
参考:#10784
URL
对象转换为字符串时,使用URL.render_as_string()
方法对用户名和密码组件进行 URL 编码的问题,通过使用 Python 标准库urllib.parse.quote
,同时允许加号和空格保持不变,以支持 SQLAlchemy 的非标准 URL 解析,而不是多年前的传统自制例程。感谢 Xavier NUNN 的拉取请求。
参考:#10662
insert()
构造)的CTE
的字符串化或编译失败的问题,由于错误地检���到语句整体为 INSERT,导致内部错误。
Table
这样的对象时,当参数本身作为元组传递时,错误报告对意外模式项的处理不正确,导致格式错误。错误消息已经更新为使用 f-strings。
参考:#10654
sqlalchemy.sql.functions
模块完成了 pep-484 类型注解。针对 func
元素进行的 select()
构造现在应该具有填充的返回类型。
参考:#6810
async_fallback
方言参数现已弃用,并将在 SQLAlchemy 2.1 中移除。这个标志在 SQLAlchemy 的测试套件中已经有一段时间没有使用了。通过使用 greenlet_spawn()
在 greenlet 中运行代码,asyncio 方言仍然可以以同步方式运行。
terminate()
方法丢弃一个无效的连接时,方言将首先尝试使用带有超时的 .close()
优雅地关闭连接,如果操作仅在异步事件循环上下文中进行。这允许 asyncpg 驱动程序处理最终化 TimeoutError
,包括能够关闭长时间运行的查询服务器端,否则该查询可能会在程序退出后继续运行。
参考:#10717
greenlet
时运行的能力。现在有一个 tox 目标,其中包含标记“nogreenlet”,将在未安装 greenlet 的情况下运行测试套件(请注意,它仍然会在 tox 配置中临时安装 greenlet)。
参考:#10747
mapped_column()
构造上使用 foreign()
注释会产生没有类型的表达式的问题,然后在实际列的初始化时不会更新,导致关系无法适当地确定 use_get
等问题的问题。
参考:#10597
MappedAsDataclass
、DeclarativeBase
和 DeclarativeBaseNoMeta
使用的 __init_subclass__()
方法,接受任意的 **kw
并将它们传播到 super()
调用,允许更灵活地安排使用 __init_subclass__()
关键字参数的自定义超类和混入。拉取请求由 Michael Oliver 提供。
参考:#10732
returning()
部分中使用的 Bundle
对象的用例经过测试并且完全可用。这在之前从未明确实现或测试过,在 1.4 系列中没有正常工作;在 2.0 系列中,具有 WHERE 条件的 ORM UPDATE/DELETE 缺少实现方法,阻止了 Bundle
对象的正常工作。
参考:#10776
MutableList
中的回归,其中检测序列的例程不会正确地过滤出字符串或字节实例,使得无法将字符串值分配给特定索引(而非序列值则正常工作)。
参考:#10784
URL.render_as_string()
方法将用户名和密码组件进行 URL 编码时的问题,通过使用 Python 标准库urllib.parse.quote
,同时允许加号和空格保持不变,以支持 SQLAlchemy 的非标准 URL 解析,而不是多年前的传统自制程序。感谢 Xavier NUNN 的拉取请求。
参考:#10662
insert()
)的CTE
进行字符串化或编译时失败的问题,由于错误地检测到语句整体是一个 INSERT,导致内部错误。
Table
)时,对于意外模式项的错误报告处理不正确的问题,该参数本身被传递为元组,导致格式化错误。错误消息已经更新为使用 f-strings。
参考:#10654
sqlalchemy.sql.functions
模块的 pep-484 类型注释。针对func
元素进行的select()
构造现在应该具有填充的返回类型。
参考:#6810
async_fallback
方言参数现已弃用,并将在 SQLAlchemy 2.1 中删除。这个标志已经有一段时间没有在 SQLAlchemy 的测试套件中使用了。通过使用greenlet_spawn()
在 greenlet 中运行代码,asyncio 方言仍然可以以同步方式运行。
terminate()
方法丢弃一个无效的连接时,方言将首先尝试使用带有超时的 .close()
优雅地关闭连接,仅在异步事件循环上下文中进行该操作时。这允许 asyncpg 驱动程序处理最终化 TimeoutError
,包括能够在程序退出后继续运行的长时间运行的查询服务器端。
参考:#10717
greenlet
时运行的能力。现在有一个 tox 目标包含标记“nogreenlet”,将以未安装 greenlet 的方式运行测试套件(注意,它仍然在 tox 配置中临时安装 greenlet)。
参考:#10747
发布日期:2023 年 11 月 2 日
Session.bulk_insert_mappings.render_nulls
参数,允许 render_nulls=True
作为执行选项。这允许参数字典中含有混合的 None
值的批量 ORM 插入使用给定的字典键的单个行批次,而不是将每个 INSERT 中的 NULL 列分开成批次。
另请参阅
在 ORM 批量 INSERT 语句中发送 NULL 值
参考:#10575
__allow_unmapped__
指令无法允许旧式 Column
/ deferred()
映射的问题,这些映射尽管没有 Mapped[]
作为它们的类型,但仍然具有诸如 Any
或特定类型的注释,并且不会出现有关定位属性名称的错误。
参考:#10516
with_expression()
结构与加载器选项 selectinload()
、lazyload()
结合使用时,在后续缓存运行中无法正确替换绑定参数值的缓存错误。
参考:#10570
ClassVar
,但仍然以某种方式引用了 ORM 映射类名,将无法解释为未映射的 ClassVar
。
参考:#10472
Interval
数据类型实现了“文字值处理”,允许文字渲染间隔值。Pull request 由 Indivar Mishra 提供。
参考:#9737
literal_execute=True
会导致错误值渲染的问题,这是由于迭代问题造成的。
此更改也已被回溯至:1.4.50
参考:#10142
TypeEngine.compare_against_backend()
。该方法被 Alembic 的非常旧的版本使用。有关详细信息,请参见 github.com/sqlalchemy/alembic/issues/1293
。
AsyncSession.close_all()
方法的错误。还添加了函数 close_all_sessions()
,它是 close_all_sessions()
的等效项。Pull request 由 Bryan 不可思议 提供。
参考:#10421
BIT
数据类型时,修复了“insertmanyvalues”的 SQL 处理。 asyncpg 上的 BIT
显然需要使用 asyncpg 特定的 BitString
类型,该类型当前在使用此 DBAPI 时公开,使其与其他所有在此处使用普通位串的 PostgreSQL DBAPI 不兼容。 在版本 2.1 中的未来修复将会使这种数据类型在所有 PG 后端上正规化。 感谢 Sören Oldag 提交的拉取请求。
参考:#10532
connection.ping()
的False
参数,该参数旨在禁用不需要的“自动重新连接”功能,在 MySQL 驱动程序和后端中被弃用,并且对于某些版本的 MySQL 本机客户端驱动程序正在产生警告。 对于 mysqlclient,它已被删除,而对于 PyMySQL 和基于 PyMySQL 的驱动程序,该参数将在某个时候被弃用并删除,因此使用 API 内省来对抗这些不同阶段的移除。
此更改也已回溯到:1.4.50
参考:#10492
True
或False
值指定Column.nullable
,则将生成的列默认设置为 NULL,因为 MariaDB 不支持具有生成列的“NOT NULL”短语。 感谢 Indivar 提交的拉取请求。
参考:#10056
aioodbc
驱动程序的支持。
另请参阅
aioodbc - 在 SQL Server 方言文档中。
参考:#6521
Interval
数据类型中修复了问题,其中 Oracle 实现未用于 DDL 生成,导致day_precision
和second_precision
参数被忽略,尽管该方言支持。感谢 Indivar 的 Pull 请求。
参考:#10509
Session.bulk_insert_mappings.render_nulls
参数,用于新样式的批量 ORM 插入,允许render_nulls=True
作为执行选项。这允许在参数字典中使用None
值的批量 ORM 插入使用给定的一组字典键的单个行批次,而不是将其拆分为省略每个 INSERT 中的 NULL 列的批次。
另请参阅
在 ORM 批量 INSERT 语句中发送 NULL 值
参考:#10575
__allow_unmapped__
指令无法允许具有Any
或没有Mapped[]
作为其类型的特定类型的注释的遗留Column
/ deferred()
映射的问题,而无需与定位属性名称相关的错误。
参考:#10516
with_expression()
结构与加载器选项 selectinload()
,lazyload()
结合使用时,与后续缓存运行中正确替换绑定参数值失败的缓存错误。
引用:#10570
ClassVar
,尽管以某种方式引用了 ORM 映射的类名,但未能被解释为未映射的 ClassVar
。
引用:#10472
Interval
数据类型的“字面值处理”,适用于 PostgreSQL 和 Oracle 方言,允许直接渲染间隔值。感谢 Indivar Mishra 提供的拉取请求。
引用:#9737
literal_execute=True
时,多次使用相同的绑定参数会由于迭代问题导致错误的值渲染。
此更改还回溯到:1.4.50
引用:#10142
TypeEngine.compare_against_backend()
,此方法仅用于非常旧版本的 Alembic。有关详细信息,请参见github.com/sqlalchemy/alembic/issues/1293
。
AsyncSession.close_all()
方法无法正常工作的错误。还添加了函数 close_all_sessions()
,它等同于 close_all_sessions()
。拉取请求由 Bryan 不可思议 提供。
引用:#10421
BIT
数据类型的 “insertmanyvalues” 的 SQL 处理问题。在 asyncpg 上,BIT
显然需要使用 asyncpg 特定的 BitString
类型,目前在使用此 DBAPI 时暴露,这使其与其他 PostgreSQL DBAPI 不兼容,所有这些 DBAPI 都在这里使用普通的位字符串。在版本 2.1 中,将通过将此数据类型在所有 PG 后端上归一化来解决此问题。拉取请求由 Sören Oldag 提供。
参考:#10532
connection.ping()
的 False
参数,用于禁用不想要的 “自动重新连接” 功能,正在被 MySQL 驱动程序和后端弃用,并且对某些版本的 MySQL 的本机客户端驱动程序产生警告。对于 mysqlclient,它已被移除,而对于 PyMySQL 和基于 PyMySQL 的驱动程序,该参数将在某个时候被弃用并移除,因此使用 API 内省来未来证明对这些移除的各个阶段进行了保护。
这个更改也被回溯到了:1.4.50
参考:#10492
Column.nullable
没有使用显式的 True
或 False
值进行指定,因为 MariaDB 不支持带有生成列的“NOT NULL”短语。拉取请求由 Indivar 提供。
参考:#10056
aioodbc
驱动添加了支持,该驱动建立在 pyodbc 和通用 aio* 方言架构之上。
另请参阅
aioodbc - 在 SQL Server 方言文档中。
参考:#6521
Interval
数据类型中的问题,在 Oracle 实现未用于 DDL 生成,导致 day_precision
和 second_precision
参数被忽略,尽管该方言支持这些参数。Indivar 提供的拉取请求。
参考:#10509
发布日期:2023 年 10 月 12 日
Session.get_one()
方法,其行为类似于 Session.get()
,但是如果未找到具有提供的主键的实例,则引发异常而不是返回 None
。由 Carlos Sousa 提供的拉取请求。
参考:#10202
Session.close_resets_only
设置为 False
将阻止在调用 Session.close()
后执行任何其他操作。
添加了新方法Session.reset()
,它将一个Session
重置为其初始状态。这是 Session.close()
的别名,除非 Session.close_resets_only
设置为False
。
参考:#7787
mapped_column()
参数,在 pep-593 Annotated
对象中使用mapped_column()
对象时未被传递,包括 mapped_column.sort_order
,mapped_column.deferred
,mapped_column.autoincrement
,mapped_column.system
,mapped_column.info
等。
另外,仍然不支持使用mapped_column.kw_only
等数据类参数,这些参数在通过Annotated
接收的mapped_column()
中指定,因为这在 pep-681 数据类转换中不受支持。当以这种方式在Annotated
中使用这些参数时,将发出警告(并且它们继续被忽略)。
参考:#10046, #10369
select()
查询调用 Result.unique()
方法时的问题,在此查询中,一个或多个列产生的值是“未知可哈希性”,通常是在使用 func.json_build_object()
等 JSON 函数时没有提供类型时会导致内部失败。在这种情况下,修复了将对象作为接收到的对象测试其可哈希性的行为,并在不可哈希时引发一个信息性错误消息。请注意,对于“已知不可哈希性”的值,例如直接使用 JSON
或 ARRAY
类型时,已经会引发一个信息性错误消息。
这里的“可哈希性测试”修复也适用于传统的 Query
,然而在传统情况下,几乎所有的查询都使用 Result.unique()
,因此这里不会发出新的警告;在这种情况下,保持了使用 id()
的传统行为,改进是一个未知类型如果被证明是可哈希的,那么现在将被独特化,而以前是不会的。
参考:#10459
implicit_returning=False
参数应用于映射的 Table
时指示“insertmanyvalues”不能在不提供主键值的情况下使用。
参考:#10453
with_loader_criteria()
不会应用于 Select.join()
的 bug,其中 ON 子句被给定为一个普通的 SQL 比较,而不是作为一个关系目标或类似的东西。
参考:#10365
Mapped
符号(如 WriteOnlyMapped
和 DynamicMapped
)的问题,假设注释是基于字符串或“未来注释”样式的。
参考:#10412
__allow_unmapped__
声明选项时的问题,其中使用集合类型(例如 list[SomeClass]
)声明的类型与使用 typing 构造 List[SomeClass]
的类型无法正确识别。由 Pascal Corpet 提供的拉取请求。
参考:#10385
Update.add_cte()
添加的 CTE(通用表达式),以提供所需的 CTE 的情况,会出现这种情况。
参考:#10408
on
属性而导致 DDL
结构不再执行 __repr__()
。由 Iuri de Silvio 提供的拉取请求。
参考:#10443
Values
的参数列表过于严格地与 List
而不是 Sequence
绑定的类型问题。由 Iuri de Silvio 提供的拉取请求。
参考:#10451
AsyncSession.get.execution_options
参数传播到底层Session
并且被忽略的问题。
cursor.rowcount
值,以适应像 Pandas 这样硬编码调用Result.rowcount
的工具。SQLAlchemy 通常仅为 UPDATE/DELETE 语句预加载cursor.rowcount
,否则会传递给 DBAPI,在那里如果没有值可用,则可以返回-1。然而,mariadb-connector 在关闭光标本身后不支持调用cursor.rowcount
,而是引发错误。已添加通用测试支持,以确保所有后端支持在结果关闭后允许Result.rowcount
成功(即返回一个整数值,-1 表示“不可用”)。
参考:#10396
select.fetch()
方法限制行数与 WITH TIES 或 PERCENT 结合使用时未被禁用,从而阻止了可以使用带有 TOP / ORDER BY 的有效子查询。
参考:#10458
Session.get()
但在未找到具有提供的主键的实例时引发异常而不是返回None
的方法Session.get_one()
。感谢 Carlos Sousa 的拉取请求。
参考:#10202
Session.close_resets_only
设置为False
将阻止Session
在调用Session.close()
后执行任何其他操作。
添加了新方法Session.reset()
,将Session
重置为初始状态。这是Session.close()
的别名,除非设置Session.close_resets_only
为False
。
参考:#7787
mapped_column()
参数,在使用Annotated
对象内部的mapped_column()
对象时未被传递,包括mapped_column.sort_order
,mapped_column.deferred
,mapped_column.autoincrement
,mapped_column.system
,mapped_column.info
等。
此外,在Annotated
中接收到
参考:#10046,#10369
select()
查询调用 Result.unique()
时的问题,在此情况下,如果一个或多个列产生的值是“未知的可哈希性”,通常是在使用像 func.json_build_object()
这样的 JSON 函数时没有提供类型时,会在返回的值实际上不可哈希时内部失败。此行为已修复,此时会对接收到的对象进行哈希性测试,如果不可哈希,则会引发一个信息性错误消息。请注意,对于“已知的不可哈希性”值,例如直接使用 JSON
或 ARRAY
类型时,已经会引发信息性错误消息。
此处的“哈希性测试”修复也适用于传统的 Query
,但在传统情况下,几乎所有查询都使用 Result.unique()
,因此此处不会发出新的警告;在这种情况下,保留了使用 id()
的传统行为,改进是现在将被证明是可哈希的未知类型现在会被唯一化,而以前则不会。
参考:#10459
implicit_returning=False
参数应用于映射的 Table
,表示如果未提供主键值,则 ORM 会意外地尝试将非 RETURNING 结果解释为带有 RETURNING 结果,表明“insertmanyvalues”不能在不提供主键值的情况下使用。
参考:#10453
with_loader_criteria()
在 ON 子句被给定为普通 SQL 比较而不是作为关系目标或类似的情况下不应用于 Select.join()
的 bug。
参考:#10365
Mapped
符号,例如 WriteOnlyMapped
和 DynamicMapped
在引用为给定注释的子模块的元素时无法正确解析的问题,假定使用基于字符串或“未来注释”样式注释。
参考:#10412
__allow_unmapped__
声明选项中的问题,其中使用集合类型(如 list[SomeClass]
)声明的类型与使用 typing 构造 List[SomeClass]
相比将无法被正确识别。 感谢 Pascal Corpet 提供的拉取请求。
参考:#10385
Update.add_cte()
添加的 CTE,以在语句顶部提供所需的 CTE。
参考:#10408
DDL
构造由于已移除的 on
属性未被容纳而不再 __repr__()
。 感谢 Iuri de Silvio 提供的拉取请求。
参考:#10443
Values
的参数列表过于严格地绑定到 List
而不是 Sequence
。 感谢 Iuri de Silvio 提供的拉取请求。
参考:#10451
AsyncSession.get.execution_options
参数传播到底层 Session
并且被忽略的问题。
cursor.rowcount
值,以适应像 Pandas 这样硬编码调用 Result.rowcount
的工具。SQLAlchemy 通常仅为 UPDATE/DELETE 语句预加载 cursor.rowcount
,否则传递给 DBAPI,在那里如果没有值可用则可以返回 -1。但是,mariadb-connector 不支持在关闭游标本身后调用 cursor.rowcount
,而是引发错误。已添加通用测试支持,以确保所有后端支持在结果关闭后允许 Result.rowcount
成功(即返回一个整数值,-1 表示“不可用”)。
参考:#10396
select.fetch()
方法限制行数与 WITH TIES 或 PERCENT 结合时被禁用,导致无法使用带有 TOP / ORDER BY 的有效子查询。
参考:#10458
发布日期:2023 年 9 月 18 日
Update
和 Delete
中,以不干扰传递给语句的目标“from”对象,例如在传递 ORM 映射的 aliased
构造时应在“UPDATE FROM”等短语中保留。像使用“SELECT”语句进行 ORM 会话同步的情况,如与 MySQL/MariaDB 一起使用此类形式的 UPDATE/DELETE 仍然会有问题,因此最好在使用此类 DML 语句时禁用 synchonize_session。
参考:#10279
selectin_polymorphic()
加载器选项添加了新的功能,允许其他加载器选项作为兄弟节点捆绑在其中,引用其子类之一,在父加载器选项的子选项中。以前,只有在查询的选项的顶层才支持此模式。参见新的文档部分示例。
作为此更改的一部分,改进了Load.selectin_polymorphic()
方法/加载策略的行为,因此在对已经关系加载的类使用该选项时,子类加载不会加载父表中已加载的大多数列。先前,仅对顶级类加载的逻辑才能仅加载子类列。
另请参阅
在 selectin_polymorphic 本身作为子选项时应用加载器选项
参考:#10348
Enum
数据类型,接受Enum.length
参数的值为None
,在生成的 DDL 中,结果为 VARCHAR 或其他文本类型而没有长度。这允许在模式中存在类型后向类型添加任意长度的新元素。感谢 Eugene Toder 的拉取请求。
参考:#10269
aggregate_strings
,接受一个 SQL 表达式和一个分隔符,将多行字符串连接为单个聚合值。该函数根据每个后端编译为诸如group_concat()
、string_agg()
或LISTAGG()
等函数。感谢 Joshua Morris 的拉取请求。
参考:#9873
ColumnElement.like()
、ColumnElement.regexp_match()
、ColumnElement.match()
等,以及与字符串比较运算符相同优先级的纯 ==
,这样括号将应用于跟在字符串匹配运算符后面的字符串连接表达式。这为后端,例如 PostgreSQL 提供了可能比字符串连接运算符优先级更高的 “regexp match” 运算符的情况。
参考:#9610
hashlib.md5()
的使用进行了限定,该函数用于在 DDL 语句中为长索引和约束名称生成确定性的四字符后缀,以包括 Python 3.9+ 中的 usedforsecurity=False
参数,以便 Python 解释器构建为诸如 FIPS 之类的受限环境时不认为此调用与安全问题有关。
参考:#10342
Values
构造现在将自动创建 column
的代理(即复制),如果该列已经与现有的 FROM 子句相关联。这允许像 values_obj.c.colname
这样的表达式即使在 colname
被传递为已经与以前的 Values
或其他表构造一起使用的 column
的情况下,也能产生正确的 FROM 子句。最初认为这可能是一个错误条件的候选项,但是很可能这种模式已经被广泛使用,所以现在添加了支持。
参考:#10280
Identity.order
参数的渲染,该参数是Sequence
和Identity
的一部分,仅适用于 Oracle 后端,而不适用于其他后端,如 PostgreSQL。未来的版本将重命名Identity.order
、Sequence.order
和Identity.on_null
参数为 Oracle 特定名称,弃用旧名称,这些参数仅适用于 Oracle。
此更改也回溯到:1.4.50
参考:#10207
Mapped
的包含类型协变;这是为了允许更大的灵活性,以满足最终用户的类型化场景,例如使用协议来表示传递给其他函数的特定映射类结构。作为此更改的一部分,还使依赖和相关类型的包含类型协变,如SQLORMOperations
、WriteOnlyMapped
和SQLColumnExpression
。拉取请求由 Roméo Després 提供。
参考:#10288
MetaData.naming_convention
添加更正式的类型化。此更改阻止了基本命名约定字典通过类型化,并已调整为再次接受键为字符串的普通字典以及使用约束类型作为键或两者混合使用的字典。
作为此更改的一部分,还对命名约定字典的较少使用形式进行了类型化,包括当前允许将Constraint
类型对象用作键。
参考:#10264, #9284
Visitable
的__class_getitem__()
的类型注释,使其接受Any
作为键,而不是str
,这有助于一些 IDE(如 PyCharm)在尝试为包含泛型选择器的 SQL 构造编写类型注释时。感谢 Jordan Macdonald 的拉取请求。
参考资料:#9878
SQLCoreOperations
以支持从类型角度来看的 __hash__()
方法,因为像 Column
和 ORM InstrumentedAttribute
这样的对象是可散列的,并且在 Update
和 Insert
构造的公共 API 中用作字典键。先前,类型检查器不知道根 SQL 元素是可散列的。
参考资料:#10353
Existing.select_from()
的类型注释问题。
参考资料:#10337
create_engine.pool_pre_ping
参数时,PostgreSQL 方言的修订“ping”会干扰 asyncpg 与 PGBouncer 的“transaction”模式的使用,因为 asnycpg 发出的多个 PostgreSQL 命令可能被分成多个连接导致错误,因为这种新修订的“ping”周围没有任何事务。现在,在事务内调用 ping,与所有其他基于 pep-249 DBAPI 的后端一样;这保证了由此命令发送的一系列 PG 命令在同一后端连接上被调用,而不是在命令执行中跳转到另一个连接。如果 asyncpg 方言以“AUTOCOMMIT”模式使用,则不使用事务,这与 pgbouncer 事务模式不兼容。
参考资料:#10226
sqlalchemy.testing.fixtures
。这适用于诸如 pkgutil
等尝试在所有包中导入所有已安装模块的检查实用程序。
参考:#10321
Update
和 Delete
中使用的“target”实体的解释,以避免干扰语句中传递的目标“from”对象,比如传递 ORM 映射的 aliased
结构,在像“UPDATE FROM”这样的短语中应保持不变。像 ORM 会话同步使用“SELECT”语句的情况,比如 MySQL/MariaDB,仍然会出现这种形式的 UPDATE/DELETE 的问题,因此最好在使用此类 DML 语句时禁用 synchonize_session。
参考:#10279
selectin_polymorphic()
加载器选项添加了新的功能,允许将其他加载器选项作为同级项捆绑在其中,引用其中一个子类,在父加载器选项的子选项中。以前,只有在查询的选项的顶级中才支持这种模式。请参阅新的文档部分以获取示例。
作为这一变化的一部分,改进了 Load.selectin_polymorphic()
方法/加载器策略的行为,以便在已经对父表进行关系加载时,子类加载不会加载大部分已加载列。以前,仅加载子类列的逻辑仅适用于顶层类加载。
参见
在 selectin_polymorphic 本身是子选项时应用加载器选项
参考:#10348
Enum
数据类型,使其接受None
参数作为Enum.length
参数,从而在生成的 DDL 中得到一个没有长度限制的 VARCHAR 或其他文本类型。这允许在模式中存在该类型后添加任意长度的新元素。感谢 Eugene Toder 的拉取请求。
参考:#10269
aggregate_strings
,接受一个 SQL 表达式和一个分隔符,将多行字符串连接成单个聚合值。该函数根据每个后端编译成函数,如group_concat()
、string_agg()
或LISTAGG()
。感谢 Joshua Morris 的拉取请求。
参考:#9873
ColumnElement.like()
、ColumnElement.regexp_match()
、ColumnElement.match()
等)以及普通的==
运算符相等,这样括号将应用于跟在字符串匹配运算符后的字符串连接表达式。这为后端(如 PostgreSQL)提供了支持,其中“regexp match”运算符显然比字符串连接运算符的优先级高。
参考:#9610
hashlib.md5()
的使用,用于为 DDL 语句中的长索引和约束名称生成确定性的四字符后缀,以包括 Python 3.9+的usedforsecurity=False
参数,以便 Python 解释器构建用于受限环境(如 FIPS)时不将此调用视为与安全问题相关。
参考:#10342
Values
构造现在将自动创建一个代理(即复制),如果列已经与现有的 FROM 子句相关联。这样一来,即使colname
已经作为一个column
被传递给了先前的Values
或其他表构造,表达式values_obj.c.colname
也会产生正确的 FROM 子句。最初认为这可能会导致错误,但很可能这种模式已经被广泛使用,所以现在添加以支持。
参考:#10280
Identity.order
参数的呈现方式,该参数既属于Sequence
又属于Identity
,现在只在 Oracle 后端生效,而不是像 PostgreSQL 那样适用于其他后端。将来的版本将会将Identity.order
、Sequence.order
和Identity.on_null
参数重命名为 Oracle 特定的名称,并弃用旧名称,这些参数仅适用于 Oracle。
此更改也回溯到:1.4.50
参考:#10207
Mapped
中包含的类型进行了协变处理;这样做是为了在端用户的类型场景中提供更大的灵活性,比如使用协议来表示特定映射类结构,这些结构会传递给其他函数。作为这一变更的一部分,对于依赖和相关类型,如SQLORMOperations
、WriteOnlyMapped
和SQLColumnExpression
,也对其中包含的类型进行了协变处理。感谢 Roméo Després 提交的拉取请求。
参考:#10288
MetaData.naming_convention
添加更正式的类型注解。这一变更阻止了基本的命名约定字典通过类型检查,并已调整为再次接受纯字符串键的普通字典以及使用约束类型作为键或两者混合使用的字典。
作为这一变更的一部分,还对命名约定字典的较少使用形式进行了类型化,其中目前允许 Constraint
类型对象作为键。
参考:#10264, #9284
Visitable
类的 __class_getitem__()
的类型注解,以接受 Any
作为键,而不是 str
,这有助于一些 IDE,如 PyCharm,在尝试为包含通用选择器的 SQL 构造编写类型注解时。感谢 Jordan Macdonald 的拉取请求。
参考:#9878
SQLCoreOperations
,以支持从类型的角度看待 __hash__()
方法,因为像 Column
和 ORM InstrumentedAttribute
这样的对象是可哈希的,并且在公共 API 中用作字典键,用于 Update
和 Insert
构造。以前,类型检查器不知道根 SQL 元素是可哈希的。
参考:#10353
Existing.select_from()
的类型问题,这阻止了它与 ORM 类的使用。
参考:#10337
create_engine.pool_pre_ping
参数时,用于 PostgreSQL 方言的修订“ping”会干扰 asyncpg 与 PGBouncer“事务”模式的使用,因为 asnycpg 发出的多个 PostgreSQL 命令可能会被分配到多个连接中,导致错误,由于对此新修订的“ping”周围没有任何事务。现在,在事务中调用 ping,就像所有其他基于 pep-249 DBAPI 的后端隐式使用的一样;这保证了由于此命令发送的 PG 命令系列会在同一后端连接上调用,而不是在命令中间跳到不同的连接。如果使用 asyncpg 方言处于“AUTOCOMMIT”模式下,则不使用事务,这仍然与 pgbouncer 事务模式不兼容。
参考资料:#10226
sqlalchemy.testing.fixtures
。这适用于诸如pkgutil
等试图导入所有包中所有已安装模块的检查工具。
参考资料:#10321
发布日期:2023 年 8 月 15 日
Select.join()
对关系目标进行连接的子查询进行的问题。在特殊情况下使用这些注释,例如在PropComparator.and_()
和其他 ORM 特定场景中使用子查询时。
此更改也被回溯到:1.4.50
参考资料:#10223
CTE
构造。。
参考资料:#10169
Session.execute()
的执行选项以及本身 ORM 执行的语句的执行选项将不会传递给 eager loaders,例如 selectinload()
、immediateload()
和 sqlalchemy.orm.subqueryload()
,从而使得禁用单个语句的缓存或者为单个语句使用 schema_translate_map
等操作变得不可能,以及使用用户自定义执行选项。已经做出了更改,即现在所有对于 Session.execute()
的用户界面执行选项都将传递到附加的 loaders 中。
作为这一更改的一部分,对于导致禁用缓存的“过度深层” eager loaders 的警告现在可以通过向 Session.execute()
发送 execution_options={"compiled_cache": None}
来在每个语句的基础上消除,这将禁用该范围内所有语句的缓存。
参考文献:#10231
Comparator.any()
这样的表达式,以生成相关 EXISTS 构造,会干扰 SQL 编译器的“笛卡尔积警告”特性,导致 SQL 编译器在语句的所有元素都正确连接时发出警告。
参考文献:#10124
lazy="immediateload"
加载策略在某些情况下会将内部加载令牌放入 ORM 映射属性中的问题,例如在递归自引用加载时不应发生加载。作为这一更改的一部分,lazy="immediateload"
策略现在与其他 eager loaders 一样尊重 relationship.join_depth
参数,对于自引用 eager 加载,如果将其设置为未设置或设置为零,将不会发生自引用 immediateload,如果将其设置为大于零的值,将会立即加载直到给定的深度。
参考文献:#10139
attribute_keyed_dict()
)未正确地完全序列化/反序列化,导致在反序列化后尝试突变此类集合时出现问题。
参考文献:#10175
aliased()
对于连接的继承子类链的超类的本地列失败时,链接load_only()
或其他通配符使用defer()
。
参考文献:#10125
select()
结构不会呈现仅通过Select.add_cte()
方法添加的任何 CTEs,而这些 CTEs 在语句中没有被引用。
参考文献:#10167
Query
和select()
在执行无效操作时。
create_engine.isolation_level
设置为AUTOCOMMIT
(而不是使用Engine.execution_options()
方法),如果临时选择了替代隔离级别,则会导致无法将“autocommit”恢复到池化连接中,使用Connection.execution_options.isolation_level
。
参考文献:#10147
Column
或其他ColumnElement
进行反序列化会失败恢复正确的“比较器”对象,该对象用于生成特定于类型对象的 SQL 表达式。
此更改也已回溯至:1.4.50
参考文献:#10213
Nullable()
和NotNullable()
,用于分别将列或 ORM 类的类型定义为可空或不可空。这些函数在运行时不起作用,返回不变的输入。
参考:#10173
Session.execute()
,将返回CursorResult
Query.with_for_update.of
参数的类型,该参数在Query.with_for_update()
中被修复为正确的类型。
_DMLColumnArgument
类型,用于传递列表达式
literal()
添加了重载,以便在未提供literal.type_
参数时推断出返回类型为 BindParameter[NullType]
ColumnElement.op()
添加了重载,以便在未提供ColumnElement.op.return_type
时推断出的类型为 Callable[[Any], BinaryExpression[Any]]
ColumnElement.__add__()
添加了缺失的重载
Pull request 由 Mehdi Gmira 提供。 参考:#9185
Session
和AsyncSession
方法中的问题,例如Session.connection()
,其中Session.connection.execution_options
参数被硬编码为不面向用户的内部类型。
参考:#10182
AsyncConnection.aclose()
作为 AsyncConnection.close()
的同义词,以及 AsyncSession.aclose()
作为 AsyncSession.close()
的同义词,添加到 AsyncConnection
和 AsyncSession
对象中,以提供与 Python 标准库 @contextlib.aclosing
构造的兼容性。拉取请求由 Grigoriev Semyon 提供。
参考:#9698
Select.join()
进行的子查询进行注释的根本问题,这些子查询在特殊情况下使用,比如在 PropComparator.and_()
和其他 ORM 特定场景中使用。
此更改也 回溯 到:1.4.50
参考:#10223
CTE
构造的问题,当递归列列表被生成时。
参考:#10169
Session.execute()
以及 ORM 执行语句本身的执行选项不会传播到selectinload()
、immediateload()
和sqlalchemy.orm.subqueryload()
等急切加载器的问题,使得无法禁用单个语句的缓存或对单个语句使用schema_translate_map
,以及使用用户自定义执行选项。已经进行了更改,所有针对Session.execute()
的用户可见执行选项都将传播到其他加载器。
作为这一变化的一部分,可以通过向Session.execute()
发送execution_options={"compiled_cache": None}
来在每个语句的基础上消除“过度深入”急切加载器导致缓存被禁用的警告,这将禁用该范围内所有语句的缓存。
参考:#10231
Comparator.any()
的表达式以产生相关的 EXISTS 结构时会干扰 SQL 编译器的“笛卡尔积警告”功能的问题,导致 SQL 编译器在所有语句元素正确连接时发出警告。
参考:#10124
lazy="immediateload"
加载策略在某些情况下会将内部加载标记放入 ORM 映射属性中的问题,例如在递归自引用加载中不应发生加载的情况。作为这一变化的一部分,lazy="immediateload"
策略现在以与其他急切加载器相同的方式尊重relationship.join_depth
参数用于自引用急切加载,其中将其未设置或设置为零将导致自引用的 immediateload 不会发生,将其设置为一个或更大的值将会 immediateload 直到给定深度。
参考:#10139
attribute_keyed_dict()
之类基于字典的集合在反序列化时未能完全正确地 pickle/unpickle 的问题,导致在反序列化后尝试修改此类集合时出现问题。
参考:#10175
aliased()
针对连接继承子类的情况下,链式调用load_only()
或其他通配符使用defer()
会导致对于超类本地列无法生效的问题。
参考:#10125
select()
构造不会呈现仅通过Select.add_cte()
方法添加的任何 CTE,而这些 CTE 在语句中没有被引用。
参考:#10167
Query
和select()
之间的区别。
create_engine.isolation_level
设置为AUTOCOMMIT
(而不是使用Engine.execution_options()
方法)会导致如果使用Connection.execution_options.isolation_level
临时选择了替代隔离级别,则无法将“autocommit”恢复到池化连接的关键问题。
参考:#10147
Column
或其他ColumnElement
时无法恢复正确的“比较器”对象的问题,该对象用于生成特定于类型对象的 SQL 表达式。
此更改也回溯到:1.4.50
参考:#10213
Nullable()
和NotNullable()
,用于分别将列或 ORM 类类型化为可空或不可空。这些函数在运行时不起作用,返回不变的输入。
参考:#10173
Session.execute()
中返回了CursorResult
,其中使用了没有返回的 DML
Query.with_for_update.of
参数的类型,在Query.with_for_update()
内部。
_DMLColumnArgument
类型进行了改进,以传递列表达式。
literal()
的重载,以便推断返回类型为BindParameter[NullType]
,其中literal.type_
参数为 None
ColumnElement.op()
的重载,以便在未提供ColumnElement.op.return_type
时推断类型为Callable[[Any], BinaryExpression[Any]]
。
ColumnElement.__add__()
的缺失重载
拉取请求由 Mehdi Gmira 提供。 参考:#9185
Session
和AsyncSession
方法中的问题,例如Session.connection()
,其中Session.connection.execution_options
参数被硬编码为不是面向用户的内部类型。
参考:#10182
AsyncConnection.aclose()
作为AsyncConnection.close()
的同义词,以及AsyncSession.aclose()
作为AsyncSession.close()
的同义词,用于AsyncConnection
和AsyncSession
对象,以与 Python 标准库@contextlib.aclosing
构造兼容。感谢 Grigoriev Semyon 提交的拉取请求。
参考:#9698
发布日期:2023 年 7 月 15 日
Session
中。这与#6471类似,并且由于在 2.0 系列中删除了cascade_backrefs
,这个问题更加明显。作为#6471的一部分,现在还为已存在于相同集合的批量设置中的现有成员触发AttributeEvents.append_wo_mutation()
事件。
参考:#10089
Session
中的加载集合相关联的对象的问题,由于在 2.0 系列中删除了 cascade_backrefs
,这些对象不会发出警告,即使它们是集合的待定成员;在其他类似情况下,当要刷新的集合包含将被实质性丢弃的未附加对象时,会发出警告。为 backref-待定集合成员添加警告增加了与可能存在或不存在的集合以及基于不同关系加载策略在不同时间可能刷新或不刷新的集合的一致性。
引用:#10090
Query
构造中引发内部属性错误,即使在这种情况下 ORM 启用的 UPDATE 和 DELETE 语句中也不包含 ORM 实体。
引用:#10098
Row.t
和 Row.tuple()
重命名为 Row._t
和 Row._tuple()
;这是为了遵循所有在Row
上的方法和预定义属性应该以 Python 标准库 namedtuple
的风格命名的政策,所有固定名称都有一个前导下划线,以避免与现有列名称发生冲突。以前的方法/属性现在已被弃用,并将发出弃用警告。
引用:#10093
make_url()
函数添加了对非字符串、非URL
对象的检测,允许立即抛出ArgumentError
,而不是在后来导致失败。特殊逻辑确保模拟形式的URL
可以通过。感谢 Grigoriev Semyon 的拉取请求。
引用:#10079
host:port
组合。解析已更新,只有当主机名仅包含字母数字字符,点或破折号(例如没有斜杠),后跟一个冒号,然后跟着一个零个或多个整数的令牌时,才将冒号视为指示host:port
值。在所有其他情况下,整个字符串被视为主机。
参考:#10069
CITEXT
数据类型的比较会将右侧转换为VARCHAR
的问题,导致右侧不被解释为CITEXT
数据类型,适用于 asyncpg、psycopg3 和 pg80000 方言。这导致CITEXT
类型在实际使用中基本上无法使用;现在已修复此问题,并且测试套件已经更正,以正确断言表达式是否被正确渲染。
参考:#10096
Session
中。这与#6471类似,并且由于在 2.0 系列中删除了cascade_backrefs
,这个问题更加明显。作为#6471的一部分添加的AttributeEvents.append_wo_mutation()
事件现在也会对已存在于同一集合的批量设置中的现有成员发出。
参考:#10089
Session
的未加载集合相关联的对象,因为在 2.0 系列中删除了cascade_backrefs
,所以不会发出警告,即这些对象未被包含在刷新中,即使它们是集合的待处理成员;在其他类似情况下,当正在刷新的集合包含将被基本丢弃的非附加对象时,将发出警告。对于反向引用挂起的集合成员添加警告,可以建立更大一致性,这些集合可能存在或不存在,并可能根据不同的关系加载策略在不同的时间进行刷新或不刷新。
参考:#10090
Query
构造的核心 SQL 语句中包含没有 ORM 实体的情况下导致内部属性错误,即使在这种情况下,ORM 启用的 UPDATE 和 DELETE 语句也不包含 ORM 实体。
参考:#10098
Row.t
和Row.tuple()
重命名为Row._t
和Row._tuple()
;这是为了符合所有方法和预定义属性在Row
上应采用 Python 标准库namedtuple
风格的政策,其中所有固定名称都带有前导下划线,以避免与现有列名称发生冲突。以前的方法/属性现已弃用,并将发出弃用警告。
参考:#10093
URL
对象的检测到make_url()
函数,允许立即抛出ArgumentError
,而不是后来导致失败。特殊逻辑确保允许通过 URL
的模拟形式。感谢 Grigoriev Semyon 的拉取请求。
参考:#10079
host:port
组合。 解析已更新为仅在主机名仅包含字母数字字符以及仅包含点或破折号(例如没有斜杠)的情况下,考虑冒号表示host:port
值,后跟零个或多个整数的全整数标记的情况下,才表示主机。 在所有其他情况下,将完整字符串视为主机。
引用:#10069
CITEXT
数据类型的比较问题,导致右侧被转换为VARCHAR
,导致右侧未被解释为CITEXT
数据类型,适用于 asyncpg、psycopg3 和 pg80000 方言。 这导致CITEXT
类型在实际使用中基本不可用;现已修复此问题,并已更正测试套件以正确断言表达式是否被正确呈现。
引用:#10096
发布日期:2023 年 7 月 5 日
create_engine.schema_translate_map
功能,使得语句中的所有模式名称现在都被标记化,而不管特定名称是否在给定的立即模式翻译映射中,并且在执行时当键不在实际模式翻译映射中时回退到替换原始名称。 这两个更改允许在每次运行时使用包含或不包含各种键的模式翻译映射来重复使用已编译的对象,从而使得当每次使用时都使用具有不同键集的模式翻译映射时,缓存的 SQL 结构可以继续在运行时正常工作。 另外,还添加了在相同语句的调用间获得或失去None
键的 schema_translate_map 字典的检测,这会影响语句的编译,并且与缓存不兼容; 这些情况下会引发异常。
引用:#10025
ColumnOperators.regexp_match()
不会产生“稳定”的缓存密钥的问题,即,缓存密钥每次都会更改,导致缓存污染。对于带有标志和实际替换表达式的 ColumnOperators.regexp_replace()
也存在相同的问题。现在,标志被表示为固定的修饰符字符串,呈现为 safestring,而不是绑定参数,替换表达式在“二进制”元素的主要部分中确定,因此它生成适当的缓存密钥。
请注意,作为此更改的一部分,ColumnOperators.regexp_match.flags
和 ColumnOperators.regexp_replace.flags
已修改为仅渲染为文字字符串,而以前它们被渲染为完整的 SQL 表达式,通常是绑定参数。这些参数应始终作为普通的 Python 字符串传递,而不是作为 SQL 表达式构造;不希望在实践中使用 SQL 表达式构造此参数,因此这是一个不兼容的更改。
此更改还修改了生成的表达式的内部结构,对于带有或不带有标志的 ColumnOperators.regexp_replace()
和带有标志的 ColumnOperators.regexp_match()
。可能已经实现了自己的正则表达式实现的第三方方言(在搜索中找不到此类方言,因此预期影响很小)需要调整结构的遍历以适应。
此更改还 回溯到:1.4.49
参考:#10042
CacheKey
构造中的问题,其中__ne__()
运算符未正确实现,导致当比较 CacheKey
实例时产生荒谬的结果。
此更改还 回溯到:1.4.49
association_proxy()
association_proxy.create_on_none_assignment
添加了新选项;当一个关联代理引用一个标量关系并被赋予值 None
,并且引用的对象不存在时,通过创建者创建一个新对象。这显然是 1.2 系列中的一个未定义行为,已经被悄悄移除了。
参考资料:#10013
sqlalchemy.sql.operators
中的独立运算符函数(例如sqlalchemy.sql.operators.eq
)时,改进了类型提示。
参考资料:#10054
aliased()
结构内部的一些类型提示,以正确接受已使用 Table.alias()
别名的 Table
对象,以及对传递为“可选择”参数的 FromClause
对象的一般支持,因为这都得到了支持。
参考资料:#10061
native_inet_types=False
,该参数指示 DBAPI 使用的转换器将 PostgreSQL 的 INET
和 CIDR
列中的行转换为 Python ipaddress
数据类型时应禁用,返回字符串。这样,编写用于这些数据类型的字符串的代码可以在无需代码更改的情况下添加此参数到 create_engine()
或 create_async_engine()
函数调用中而迁移到 asyncpg、psycopg 或 pg8000。
请参阅
网络数据类型
参考:#9945
UUID
列。这使得 Alembic 能够正确地检测现有 MariaDB 数据库中这些列的类型。
参考:#10028
mssql_columnstore=True
的索引上指定。
参考:#7340
Cast
时会在 CAST 函数内部呈现 COLLATE 子句的问题,从而导致语法错误。
参考:#9932
create_engine.schema_translate_map
功能,使得语句中的所有模式名称现在都被标记化,无论指定了具体名称是否在立即模式翻译映射中,都会在执行时回退到原始名称。这两个变化允许对具有包含或不包含不同键集的模式翻译映射的编译对象进行重复使用,每次运行时使用不同的模式翻译映射,从而使得缓存的 SQL 构造在运行时继续工作。此外,增加了在同一语句的不同调用中增加或减少 None
键的 schema_translate_map 字典的检测,这会影响语句的编译,并且不兼容缓存;对于这些情况,会引发异常。
参考:#10025
ColumnOperators.regexp_match()
未生成“稳定”缓存键的问题,即每次缓存键都会发生变化,导致缓存污染。相同的问题也存在于带有 flags 和实际替换表达式的 ColumnOperators.regexp_replace()
中。现在,flags 被表示为固定的修改器字符串,呈现为安全字符串,而不是绑定参数,并且替换表达式在“binary”元素的主要部分内建立,以生成适当的缓存键。
注意,作为这一变更的一部分,ColumnOperators.regexp_match.flags
和 ColumnOperators.regexp_replace.flags
已经修改为仅呈现为字面字符串,而以前它们呈现为完整的 SQL 表达式,通常是绑定参数。这些参数应始终作为普通的 Python 字符串传递,而不是作为 SQL 表达式构造;预计实践中不会使用 SQL 表达式构造来传递此参数,因此这是一个不兼容的变更。
此变更还修改了生成的表达式的内部结构,用于带有或不带有 flags 的 ColumnOperators.regexp_replace()
,以及带有 flags 的 ColumnOperators.regexp_match()
。可能已经实现了自己的正则表达式的第三方方言(在搜索中找不到这样的方言,因此预期影响很小)需要调整结构的遍历以适应。
此变更还 回溯 到:1.4.49
参考文献:#10042
CacheKey
构造中 __ne__()
运算符未正确实现的问题,导致在将 CacheKey
实例相互比较时产生荒谬的结果。
此变更还 回溯 到:1.4.49
association_proxy()
添加了新选项association_proxy.create_on_none_assignment
; 当将引用标量关系的关联代理分配为None
值时,并且引用的对象不存在时,通过创建器创建一个新对象。在 1.2 系列中,这显然是一种未定义的行为,被默默删除了。
参考:#10013
sqlalchemy.sql.operators
的独立运算符函数(如sqlalchemy.sql.operators.eq
)时,改进了类型提示。
参考:#10054
aliased()
构造中的一些类型提示,以正确接受已使用Table.alias()
别名的Table
对象,以及一般性对于FromClause
对象作为“selectable”参数的支持,因为这都是受支持的。
参考:#10061
native_inet_types=False
,指示 DBAPI 使用的转换器将 PostgreSQL INET
和CIDR
列的行转换为 Python ipaddress
数据类型时应禁用,而是返回字符串。这允许为这些数据类型编写使用字符串的代码迁移到 asyncpg、psycopg 或 pg8000 而无需其他代码更改,只需将此参数添加到create_engine()
或create_async_engine()
函数调用中。
参见
网络数据类型
参考:#9945
UUID
列。 这使得 Alembic 能够正确地检测到现有 MariaDB 数据库中此类列的类型。
参考:#10028
mssql_columnstore=True
的索引上指定。
参考:#7340
Cast
时会在 CAST 函数内部呈现 COLLATE 子句的问题,这导致语法错误。
参考:#9932
发布日期:2023 年 6 月 23 日
undefer_group()
与selectinload()
或subqueryload()
的查询会引发AttributeError
。 拉取请求由 Matthew Martin 提供。
参考:#9870
declared_attr
在未返回Mapped
数据类型的混合类型上使用,而是返回了诸如AssociationProxy
之类的补充 ORM 数据类型。 声明式运行时会错误地尝试解释此注释为需要Mapped
并引发错误。
参考:#9957
declared_attr
函数的AssociationProxy
返回类型被禁止的类型问题。
参考:#9957
mapped_column.default
参数时,同时设置init=False
会将此值解释为 Dataclass 默认值,该值将直接分配给对象的新实例,绕过了作为底层Column.default
值生成器的默认生成器所发生的情况。现在检测到此条件以保持先前的行为,但发出了对此模棱两可用法的弃用警告;为了为Column
填充默认生成器,应使用mapped_column.insert_default
参数,该参数使其与固定名称的mapped_column.default
参数相区分,根据 pep-681。
参考:#9936
Session
“状态更改”系统进行了额外的强化和文档编写,该系统检测到Session
和AsyncSession
对象的并发使用;在从底层引擎获取连接的过程中添加了额外的检查,在内部连接管理方面是一个关键部分。
参考:#9973
of_type()
关系链中横跨长链的contains_eager()
加载器选项以正确生效于查询中。
参考:#10006
registry.type_annotation_map
中首次添加的 Enum
数据类型支持中的问题,其中使用映射中的自定义 Enum
并且在映射中使用固定配置会导致传输 Enum.name
参数失败,其中一个问题是如果枚举值作为单独的值传递,则会阻止 PostgreSQL 枚举正常工作。逻辑已更新,使“name”被传输,但也使默认的 Enum
不会设置一个硬编码的名称为 "enum"
。
参考:#9963
relationship()
和其他 MapperProperty
对象同时分配给两个不同的类属性时,会发出警告;只会映射其中一个属性。对于此情况的警告已经适用于 Column
和 mapped_column
对象。
参考:#3532
WriteOnlyMapped
和 DynamicMapped
属性在 ORM 查询中完全使用的类型问题。
参考:#9985
undefer_group()
与selectinload()
或subqueryload()
的查询会引发AttributeError
。感谢 Matthew Martin 提交的拉取请求。
参考:#9870
Mapped
数据类型的混合使用declared_attr
,而是返回了诸如AssociationProxy
等补充的 ORM 数据类型。声明式运行时错误地尝试将此注释解释为需要Mapped
并引发错误。
参考:#9957
declared_attr
函数中的AssociationProxy
返回类型被禁止的类型问题。
参考:#9957
mapped_column.default
参数时,同时设置 init=False
会将此值解释为 Dataclass 的默认值,该值将直接分配给对象的新实例,绕过了基础 Column.default
值生成器在 Column
上发生的默认生成器。现在检测到这种情况以保持先前的行为,但是对于这种模棱两可的使用会发出弃用警告;要为 Column
填充默认生成器,应使用 mapped_column.insert_default
参数,该参数与 mapped_column.default
参数相区分,其名称固定为 pep-681。
参考:#9936
Session
的“状态更改”系统进行了额外的加固和文档编制,该系统检测到同时使用 Session
和 AsyncSession
对象;在获取来自底层引擎的连接过程中添加了额外的检查,这是关于内部连接管理的关键部分。
参考:#9973
contains_eager()
加载选项,以在查询中产生正确的效果。
参考:#10006
registry.type_annotation_map
中首次添加的 Enum
数据类型支持中出现的问题,该问题涉及使用映射中的固定配置的自定义 Enum
时会失败传输 Enum.name
参数,其中,如果将枚举值作为单独的值传递,则会导致阻止 PostgreSQL 枚举起作用的问题。逻辑已更新,使“name”被传递,但同时也确保了默认 Enum
不会设置硬编码的名称为"enum"
。
引用:#9963
relationship()
和其他 MapperProperty
对象同时分配给两个不同的类属性时,会发出警告;只有其中一个属性会被映射。对于这种情况的警告已经存在于 Column
和 mapped_column
对象中。
引用:#3532
WriteOnlyMapped
和DynamicMapped
属性在 ORM 查询中无法完全使用。
引用:#9985
发布日期:2023 年 6 月 10 日
DeferredReflection.prepare()
,接受任意的 **kw
参数,这些参数将传递给 MetaData.reflect()
,允许用例,例如反射视图以及传递特定于方言的参数。此外,现代化了 DeferredReflection.prepare.bind
参数,使得一个 Engine
或 Connection
都可作为“bind”参数。
参考:#9828
DeclarativeBaseNoMeta
声明基类无法与非映射的混入或抽象类一起使用的问题,而是引发 AttributeError
。
参考:#9862
validates.include_backrefs
的默认值在 validates()
函数中更改为 False
。现在将此默认值恢复为 True
。
参考:#9820
default
值并设置 init=False
的数据类字段不起作用。在这种情况下,数据类的行为是在类上设置默认值,这与 SQLAlchemy 使用的描述符不兼容。为了支持这种情况,生成数据类时将默认值转换为 default_factory
。
参考:#9879
Mapper
上添加属性时,如果已经配置了 ORM 映射属性,或者类上已经存在属性,则会发出弃用警告。以前,对于这种情况有一个不一致地发出的非弃用警告。对于这个警告的逻辑已经改进,以便检测到终端用户替换属性,同时不会误报内部声明式和其他情况,其中替换描述符为新描述符是预期的。
参考:#9841
registry.map_imperatively()
方法的 map_imperatively.local_table
参数上的参数检查,确保仅传递 Table
或其他 FromClause
,而不是现有的映射类,这会导致未定义的行为,因为对象将进一步解释为新的映射。
参考:#9869
InstanceState.unloaded_expirable
属性是 InstanceState.unloaded
的同义词,现已弃用;此属性始终是特定于实现的,并且不应该是公共的。
参考:#9913
create_async_engine()
中添加了新的 create_async_engine.async_creator
参数,其作用与 create_engine()
的 create_engine.creator
参数相同。这是一个无参数可调用对象,使用 asyncio 数据库驱动程序直接提供新的 asyncio 连接。create_async_engine()
函数将在适当的结构中包装驱动程序级连接。拉取请求由杰克·沃瑟斯普恩提供。
参考:#8215
NAME
列转换为 TEXT
当使用 ARRAY_AGG
时。这似乎提高了与一些不支持 NAME
类型聚合的 PostgreSQL 派生产品的兼容性。
参考:#9838
NULLS NOT DISTINCT
特性的支持,使用方言选项 postgresql_nulls_not_distinct
。更新了反射逻辑,以正确考虑此选项。感谢 Pavel Siarchenia 的拉取请求。
参考:#8240
@>
。之前的优先级错误,导致在与 ANY
或 ALL
结构渲染时括号错误。
参考:#9836
ColumnOperators.like.escape
和类似参数不允许空字符串作为传递的“转义”字符的问题;这是 PostgreSQL 支持的语法。感谢 Martin Caslavsky 的拉取请求。
参考:#9907
DeferredReflection.prepare()
,接受传递给 MetaData.reflect()
的任意 **kw
参数,允许用例如反射视图以及传递方言特定参数。此外,现代化了 DeferredReflection.prepare.bind
参数,以便接受 Engine
或 Connection
作为“bind”参数。
参考:#9828
DeclarativeBaseNoMeta
声明基类无法与非映射混入类或抽象类一起使用的问题,而是引发 AttributeError
。
参考:#9862
validates.include_backrefs
的默认值在 validates()
函数中被更改为 False
。现在将此默认值恢复为 True
。
参考:#9820
default
值并设置 init=False
的 dataclasses 字段不起作用的问题。在这种情况下,dataclasses 的行为是在类上设置默认值,这与 SQLAlchemy 使用的描述符不兼容。为了支持这种情况,在生成 dataclass 时将默认值转换为 default_factory
。
参考:#9879
Mapper
添加属性时,如果已经配置了 ORM 映射属性,或者类上已经存在属性,则会发出弃用警告。以前,对于这种情况,存在一个不一致发出的非弃用警告。现在已经改进了此警告的逻辑,以便在检测到用户替换属性时发出警告,同时不会对内部 Declarative 和其他情况产生误报,其中预期使用新描述符替换旧描述符。
参考:#9841
registry.map_imperatively()
方法的 map_imperatively.local_table
参数的参数检查,确保只传递了 Table
或其他 FromClause
,而不是已存在的映射类,因为这将导致对象在进一步解释时出现未定义的行为。
参考:#9869
InstanceState.unloaded_expirable
属性是 InstanceState.unloaded
的同义词,并已弃用;此属性始终是特定于实现的,不应公开。
参考:#9913
create_async_engine()
添加了新的 create_async_engine.async_creator
参数,它实现了与 create_engine()
的 create_engine.creator
参数相同的目的。这是一个无参数的可调用对象,提供一个新的 asyncio 连接,直接使用 asyncio 数据库驱动程序。create_async_engine()
函数将以适当的结构包装驱动程序级别的连接。感谢 Jack Wotherspoon 提交的拉取请求。
参考:#8215
NAME
列转换为 TEXT
。这似乎提高了与一些 PostgreSQL 派生产品的兼容性,这些产品可能不支持在 NAME
类型上进行聚合。
参考:#9838
NULLS NOT DISTINCT
特性的支持,该特性使用方言选项 postgresql_nulls_not_distinct
。 更新了反射逻辑以正确考虑此选项。 Pavel Siarchenia 的 Pull request 提供支持。
参考:#8240
@>
。 之前优先级错误,导致在与 ANY
或 ALL
结构进行渲染时出现错误的括号。
参考:#9836
ColumnOperators.like.escape
和类似参数不允许空字符串作为参数,该参数将作为“转义”字符传递;这是 PostgreSQL 支持的语法。 感谢 Martin Caslavsky 的 Pull requset。
参考:#9907
发布日期:2023 年 5 月 19 日
Session.execute()
和相关方法更好,即使对于纯粹的 Core SQL 构造也是如此。 但是,这可能仍然会影响不期望的遗留情况,并且可能更多地成为 2.1 版本的事情。 然而,目前“ORM 标志”的规则已经放宽,因此任何语句,包括在 WHERE / ORDER BY / GROUP BY 子句中的 ORM 实体或属性,在标量子查询中等都将启用此标志。 这将导致对这些语句进行“自动刷新”,并且还可以通过 ORMExecuteState.is_orm_statement
事件级属性可见。
参考:#9805
Uuid
数据类型,以充分利用 PG 特定的 UUID
方言特定数据类型,当选择“native_uuid”时,以便包含 PG 驱动程序的行为。由于作为#9618的一部分进行的 insertmanyvalues 改进,这个问题变得明显,类似于#9739,asyncpg 驱动程序对数据类型转换的存在与否非常敏感,当使用这种通用类型时,必须调用 PostgreSQL 驱动程序特定的本地 UUID
数据类型,以便进行这些转换。
参考:#9808
Session.execute()
和相关方法更好,即使是纯粹的 Core SQL 构造。然而,这可能会影响到不期望的遗留情况,可能更多是 2.1 的事情。但是,目前,“ORM-flag”的规则已经放宽,以便包含 ORM 实体或属性的语句中的任何地方,包括仅在 WHERE / ORDER BY / GROUP BY 子句中,在标量子查询中等,将启用此标志。这将导致这些语句发生“autoflush”,并且还可以通过ORMExecuteState.is_orm_statement
事件级属性可见。
参考:#9805
Uuid
数据类型,使其在选择“native_uuid”时充分利用了 PostgreSQL 方言的 PG 特定 UUID
方言特定数据类型,以便包含 PG 驱动程序的行为。这个问题由于作为#9618的一部分所做的 insertmanyvalues 改进而变得显而易见,其中与#9739类似,asyncpg 驱动程序对是否存在数据类型转换非常敏感,当使用此通用类型时,必须调用 PostgreSQL 驱动程序特定的本地 UUID
数据类型,以便进行这些转换。
参考:#9808
发布日期:2023 年 5 月 18 日
JoinedLoader
的实现,在一个特定的区域使用了更简单的方法,之前它使用了一个缓存结构,该结构将在线程之间共享。这样做的原因是避免潜在的竞争条件,这被怀疑是导致特定崩溃的原因。所涉及的缓存结构最终仍然通过编译后的 SQL 缓存“缓存”,因此不预期出现性能下降。
参考:#9777
CTE
构造中使用 update()
或 delete()
,然后在 select()
中使用会引发 CompileError
的回归,原因是 ORM 相关规则执行 ORM 级别的更新/删除语句。
参考:#9767
ForeignKey
(或其他列级约束)位于 mapped_column()
中,然后通过 pep-593 Annotated
复制到模型中时,将每个约束的副本应用到目标 Table
中的 Column
,从而导致不正确的 CREATE TABLE DDL 以及 Alembic 下的迁移指令。
参考:#9766
joinedload()
加载器选项时,使用附加的关系条件的问题,其中附加的条件本身包含引用加入实体的相关子查询,因此还需要对别名实体进行“调整”,否则会排除这种调整,导致 joinedload 的 ON 子句错误。
References: #9779
try_cast()
函数泛化为`sqlalc