SqlAlchemy 2.0 中文文档(六十四)(3)https://developer.aliyun.com/article/1560873
0.9.4
发布日期:2014 年 3 月 28 日
一般
- [general] [feature]
已添加对 pytest 的支持以运行测试。目前,此运行程序除了 nose 外还得到支持,并且将来可能更倾向于使用 pytest。SQLAlchemy 使用的 nose 插件系统已被拆分,以便在 pytest 下也能正常工作。目前没有计划放弃对 nose 的支持,我们希望测试套件本身可以继续保持对测试平台的中立性。请查看 README.unittests.rst 文件以获取有关使用 pytest 运行测试的更新信息。
测试插件系统还增强了对一次针对多个数据库 URL 运行测试的支持,通过多次指定--db
和/或--dburi
标志。这不会为每个数据库运行整个测试套件,而是允许特定于某些后端的测试用例在运行测试时使用该后端。当使用 pytest 作为测试运行器时,系统还将多次运行特定的测试套件,每个数据库运行一次,特别是那些在“方言套件”中的测试。计划是增强系统还将被 Alembic 使用,并允许 Alembic 在一次运行中针对多个后端运行迁移操作测试,包括 Alembic 本身不包含的第三方后端。还鼓励第三方方言和扩展标准化使用 SQLAlchemy 的测试套件作为基础;请参阅 README.dialects.rst 文件以了解从 SQLAlchemy 的测试平台构建的背景。 - [general] [bug]
调整了setup.py
文件以支持将来可能从 setuptools 中删除setuptools.Feature
扩展。如果不存在此关键字,设置将仍然成功使用 setuptools 而不是退回到 distutils。现在还可以通过设置 DISABLE_SQLALCHEMY_CEXT 环境变量来禁用 C 扩展构建。无论 setuptools 是否可用,此变量都有效。
此更改也回溯到:0.8.6
参考:#2986 - [general] [bug]
修复了在 Python 3.4 中发生的一些测试/功能失败,特别是用于包装“列默认”可调用对象的逻辑对于 Python 内置函数不起作用。
参考:#2979
orm
- [orm] [feature]
新增参数mapper.confirm_deleted_rows
。默认为 True,表示一系列 DELETE 语句应确认游标行数与应匹配的主键数量相匹配;这种行为在大多数情况下已被取消(除非使用 version_id),以支持自引用 ON DELETE CASCADE 的不寻常边缘情况;为了适应这一点,消息现在只是一个警告,而不是异常,并且可以使用该标志指示期望自引用级联删除的映射。另请参见#2403以了解有关原始更改的背景。
参考:#3007 - [orm] [feature]
如果将MapperEvents.before_configured()
或MapperEvents.after_configured()
事件应用于特定的映射器或映射类,则会发出警告,因为这些事件仅在通用级别上为Mapper
目标调用。 - [orm] [feature]
添加了一个新的关键字参数once=True
到listen()
和listens_for()
。这是一个方便的功能,它将包装给定的监听器,使其只调用一次。 - [orm] [feature]
添加了一个新选项到relationship.innerjoin
,即指定字符串"nested"
。当设置为"nested"
时,与True
相反,连接的“链”将在现有外连接的右侧括起内连接,而不是将其链接为一串外连接。当 0.9 发布时,这可能本应该是默认行为,因为我们在 ORM 中引入了右嵌套连接的功能,但是目前我们将其保留为非默认行为,以避免进一步的意外。
请参阅
在联接的急切加载中可用的右嵌套内连接
参考:#2976 - [orm] [bug]
修复了 ORM 中的一个 bug,即更改对象的主键,然后将其标记为 DELETE 会失败,无法定位正确的行进行 DELETE 操作。
此更改还被回溯到:0.8.6
参考:#3006 - [orm] [bug]
修复了从 0.8.3 中的回归,因为#2818的结果是Query.exists()
在只有一个Query.select_from()
条目但没有其他实体的查询上不起作用。
此更改还被回溯到:0.8.6
参考:#2995 - [orm] [bug]
改进了一个错误消息,如果对非可选择的内容进行了查询(例如literal_column()
),然后尝试使用Query.join()
使“左”侧确定为None
,然后失败。现在明确检测到了这种情况。
此更改也回溯到:0.8.6 - [orm] [bug]
从sqlalchemy.orm.interfaces.__all__
中删除了过时的名称,并使用当前名称进行刷新,以便再次从此模块进行import *
操作。
此更改也回溯到:0.8.6
参考:#2975 - [orm] [bug]
修复了一个非常古老的行为,即一对多的延迟加载可能不适当地拉入父表,并且根据父表中的内容返回不一致的结果,当主连接包含某种针对父表的鉴别器时,例如and_(parent.id == child.parent_id, parent.deleted == False)
。虽然这种主连接对于一对多来说并没有太多意义,但当应用于多对一方时稍微更常见,并且一对多是由反向引用产生的。在这种情况下加载child
的行将保持查询中的parent.deleted == False
不变,从而将其拉入 FROM 子句并执行笛卡尔积。新行为现在将适当地替换本地“parent.deleted”的值以用于该参数。尽管通常,一个真实的应用程序可能希望在任何情况下为 o2m 方面使用不同的主连接。
参考:#2948 - [orm] [bug]
改进了“如何从 A 连接到 B”的检查,以便当一个表具有多个、复合的外键指向一个父表时,relationship.foreign_keys
参数将被正确解释以解决歧义;以前,这种情况会引发存在多个 FK 路径,而实际上 foreign_keys 参数应该确定哪一个是预期的。
参考:#2965 - [orm] [bug]
为尚未完全记录的insert=True
标志添加了对listen()
与 mapper / instance 事件一起工作的支持。 - [orm] [bug] [engine]
修复了一个 bug,即在类级别设置监听事件(例如在Mapper
或ClassManager
级别,而不是在单个映射类上,以及在Connection
上,同时还使用了内部参数转换(在这些类别中大多数情况下)会导致无法移除。
参考:#2973 - [orm] [bug]
修复了从 0.8 版本开始的回归问题,即在使用像lazyload()
这样的选项与“通配符”表达式(例如,"*"
)时,在查询中没有包含任何实际实体的情况下,会触发断言错误。这个断言是为其他情况准备的,并且意外地捕获了这种情况。 - [orm] [bug] [sqlite]
对 SQLite“联接重写”进行了更多修复;在 0.9.3 版本发布前实施的来自#2967的修复影响了 UNION 包含嵌套联接的情况。 “联接重写”是一个具有广泛可能性的功能,并且是我们多年来引入的第一个复杂的“SQL 重写”功能,因此我们正在进行许多迭代(不像 0.2/0.3 系列中的急切加载,0.4/0.5 中的多态加载)。我们应该很快就会到达目的地,所以感谢您的耐心等待:)。
引用:#2969
例子
- [examples] [bug]
修复了版本化历史示例中的错误,其中列级别的 INSERT 默认值会阻止写入 NULL 的历史值。
engine
- [engine] [feature]
为方言级事件添加了一些新的事件机制;最初的实现允许事件处理程序重新定义任意方言调用 DBAPI 游标的 execute()或 executemany()的具体机制。此时的新事件在某种程度上是半公开和试验性的,支持即将推出的一些与事务相关的扩展。 - [engine] [feature]
现在可以在一个或多个Connection
对象已创建后(例如通过 ormSession
或通过显式连接)与Engine
相关联事件监听器,并且该监听器将捕获这些连接的事件。以前,出于性能考虑,事件传输从Engine
到Connection
仅在初始化时进行,但是我们内联了一堆条件检查以使此成为可能,而不需要任何额外的函数调用。
引用:#2978 - [engine] [bug]
对于Engine
在检测到“断开”条件时重新使用连接池的机制进行了重大改进;不再丢弃池并显式关闭连接,而是保留池并更新“生成”时间戳以反映当前时间,从而在下次检出时重新使用所有现有连接。这极大地简化了回收过程,消除了等待旧池的“唤醒”连接尝试的需要,并消除了在回收操作期间可能创建的许多立即丢弃的“池”对象的竞争条件。
参考:#2985 - [引擎] [错误]
ConnectionEvents.after_cursor_execute()
事件现在被发射到Connection
的“_cursor_execute()”方法中;这是用于诸如在 INSERT 语句之前执行序列等快速执行器,以及用于方言启动检查(如 unicode 返回、字符集等)的“快速”执行器。ConnectionEvents.before_cursor_execute()
事件已经在这里被调用。这里的“executemany”标志现在总是设置为 False,因为此事件始终对应单个执行。以前,如果我们代表 executemany INSERT 语句执行操作,该标志可能为 True。
sql
- [sql] [特性]
增加了对布尔值的文字渲染支持,例如“true” / “false”或“1” / “0”。 - [sql] [特性]
添加了一个新功能conv()
,其目的是将约束名称标记为已经应用了命名约定。从 Alembic 0.6.4 开始,Alembic 迁移将使用此令牌,以便在迁移脚本中呈现已标记为已经受到命名约定影响的约束。 - [sql] [特性]
为了帮助依赖于向构造添加临时关键字参数的现有方案,已增强了模式级构造的方言级关键字参数系统。
例如,Index
这样的构造将再次在构造后接受Index.kwargs
集合中的临时关键字参数:
idx = Index("a", "b") idx.kwargs["mysql_someargument"] = True
- 为了适应允许在构建时使用自定义参数的用例,
DialectKWArgs.argument_for()
方法现在允许进行此注册:
Index.argument_for("mysql", "someargument", False) idx = Index("a", "b", mysql_someargument=True)
- 参见
DialectKWArgs.argument_for()
参考:#2866, #2962 - [sql] [bug]
修复了tuple_()
构造中的错误,其中基本上第一个 SQL 表达式的“类型”将被应用为比较元组值的“比较类型”;这在某些情况下会导致不适当的“类型转换”发生,例如当元组中混合了字符串和二进制值时,错误地将目标值转换为二进制,即使左侧的值不是二进制。tuple_()
现在在其值列表中期望异构类型。
此更改也 回溯 至:0.8.6
参考:#2977 - [sql] [bug]
修复了 0.9 版本中的一个回归,即Table
如果无法正确反映则不会从父MetaData
中删除,即使处于无效状态。 Pullreq 由 Roman Podoliaka 提供。
参考:#2988 - [sql] [bug]
MetaData.naming_convention
特性现在还将应用于与Column
直接关联的CheckConstraint
对象,而不仅仅是Table
。 - [sql] [bug]
修复了新的MetaData.naming_convention
特性中的错误,在使用“%(constraint_name)s”标记的检查约束的名称会为布尔或枚举类型生成的约束而重复,而总体重复的事件将导致“%(constraint_name)s”标记不断增加。
参考:#2991 - [sql] [bug]
当接收到没有名称的BindParameter
时,调整了将名称应用于 .c 集合的逻辑,例如通过literal()
或类似方式;绑定参数的“键”被用作 .c 内的键,而不是呈现的名称。由于这些绑定在任何情况下都具有“匿名”名称,这使得在可选地中,如果它们未被标记,那么单个绑定参数可以拥有自己的名称。
参考:#2974 - [sql] [bug]
当呈现具有重复列的FromClause.c
集合时,对其行为进行了一些更改。仍然存在发出警告并用相同名称替换旧列的行为,以某种程度上保持向后兼容性。然而,替换的列现在仍然与c
集合相关联,现在在一个集合._all_columns
中,这由诸如别名和联合之类的结构使用,以处理c
中的列集合更接近于实际列列表而不是唯一的键名称集合。这有助于处理在联合等中使用具有相同命名列的 SELECT 语句的情况,以便联合可以按位置匹配列,并且在这里仍然有一些使用FromClause.corresponding_column()
的机会(它现在可以返回一个仅在 selectable.c._all_columns 中而不是以其他方式命名的列)。新集合加下划线是因为我们仍然需要决定此列表可能会结束的位置。从理论上讲,它将成为 iter(selectable.c)的结果,但这意味着迭代的长度将不再匹配 keys()的长度,需要检查该行为。
参考:#2974 - [sql] [bug]
修复了新的TextClause.columns()
方法中列的顺序位置上不会被保留的问题。这可能会在类似于将生成的TextAsFrom
对象应用于联合的位置情况中产生潜在影响。
postgresql
- [postgresql] [feature]
对于 psycopg2 DBAPI,启用了“合理的多行计数”检查,因为这似乎是作为 psycopg2 2.0.9 的支持。
此更改也被反向移植到:0.8.6 - [postgresql] [bug]
修复了由发布 0.8.5 / 0.9.3 的兼容性增强引起的回归,其中针对仅���用于 8.1、8.2 系列的 PostgreSQL 版本的索引反射再次出现问题,围绕着一直存在问题的 int2vector 类型。虽然从 8.1 开始,int2vector 支持数组操作,但显然从 8.3 开始才支持将其转换为 varchar。
这个更改也被回溯到了:0.8.6
参考:#3000
mysql
- [mysql] [bug]
调整了 mysql-connector-python 的设置;在 Py2K 中,“supports unicode statements”标志现在为 False,因此 SQLAlchemy 将在发送到数据库之前将SQL 字符串(注意:不是参数)编码为字节。这似乎允许所有与 unicode 相关的测试通过 mysql-connector,包括那些使用非 ascii 表/列名称以及使用 unicode 在 cursor.executemany()下的 TEXT 类型的一些测试。
oracle
- [oracle] [feature]
向 cx_Oracle 方言添加了一个新的引擎选项coerce_to_unicode=True
,它将 cx_Oracle 的输出类型处理程序方法恢复到 Python 2 中的 Unicode 转换,这是因为在 0.9.2 中由于#2911而被移除。一些用例希望对所有字符串值进行 Unicode 强制转换,尽管存在性能问题。拉取请求由 Christoph Zwerschke 提供。
参考:#2911 - [oracle] [bug]
添加了新的数据类型DATE
,它是DateTime
的子类。由于 Oracle 本身没有“datetime”类型,而只有DATE
,因此在 Oracle 方言中,将DATE
类型作为DateTime
的实例是合适的。这个问题并不会改变类型的行为,因为数据转换无论如何都是由 DBAPI 处理的,但是改进的子类布局将有助于检查类型以实现跨数据库兼容性。此外,从 Oracle 方言中删除了大写的DATETIME
,因为在该上下文中这种类型是无效的。
参考:#2987
测试
- [tests] [bug]
修复了一些错误的u''
字符串,这些字符串会导致在 Py3.2 中无法通过测试。补丁由 Arfrever Frehtes Taifersar Arahesis 提供。
参考:#2980
杂项
- [bug] [ext]
修复了可变扩展中的错误以及flag_modified()
中的 bug,在这种情况下,如果属性已重新分配给自身,则更改事件将不会传播。
这个更改也被回溯到了:0.8.6
参考:#2997 - [错误] [自动映射] [扩展]
为自动映射添加了支持,当关系不应该在两个类之间创建时,这两个类处于联合继承关系中,针对将子类链接回超类的外键。
参考:#3004 - [错误] [池]
在SingletonThreadPool
中修复了一个小问题,即在“清理”过程中当前要返回的连接可能会在无意中被清除。修补程序提供 jd23。 - [错误] [扩展] [Py3k]
在关联代理中修复了一个错误,在该错误中,赋予一个空切片(例如x[:] = [...]
)在 Py3k 上会失败。 - [错误] [扩展]
修复了一个与 #2810 相关的关联代理中的回归,该回归导致一个用户提供的“getter”在从非存在目标获取标量值时不再接收到None
值。此更改引入的 None 检查现在移至默认 getter 中,因此用户提供的 getter 也将再次接收到 None 值。
参考:#2810
通用
- [通用] [特性]
添加了对 pytest 运行测试的支持。此运行器目前正在额外支持 nose,并且将来可能更倾向于使用 pytest。SQLAlchemy 使用的 nose 插件系统已分离出来,以便它也能在 pytest 下工作。目前没有计划放弃对 nose 的支持,我们希望测试套件本身可以继续尽可能保持与测试平台的不可知性。请参阅 README.unittests.rst 文件,了解使用 pytest 运行测试的更新信息。
测试插件系统还增强了,支持一次性针对多个数据库 URL 运行测试,通过多次指定--db
和/或--dburi
标志。这不会针对每个数据库运行整个测试套件,而是允许特定于某些后端的测试用例在运行测试时使用该后端。当将 pytest 作为测试运行器时,系统还将多次运行特定的测试套件,每个数据库运行一次,特别是“方言套件”中的测试。计划增强的系统也将由 Alembic 使用,并允许 Alembic 在一个运行中针对多个后端运行迁移操作测试,包括 Alembic 本身未包含的第三方后端。还鼓励第三方方言和扩展标准化为 SQLAlchemy 的测试套件作为基础;请参阅 README.dialects.rst 文件,了解从 SQLAlchemy 的测试平台构建的背景信息。 - [通用] [错误]
调整了setup.py
文件,以支持将来可能从 setuptools 中删除setuptools.Feature
扩展。如果不存在此关键字,则设置仍将成功使用 setuptools 而不是退回到 distutils。现在还可以通过设置 DISABLE_SQLALCHEMY_CEXT 环境变量来禁用 C 扩展构建。无论 setuptools 是否可用,此变量都有效。
此更改也被回溯到:0.8.6
参考:#2986 - [通用] [错误]
修复了在 Python 3.4 中发生的一些测试/特性失败,特别是用于包装“列默认值”可调用对象的逻辑对于 Python 内置函数不起作用。
参考:#2979
orm
- [ORM] [特性]
添加了新参数mapper.confirm_deleted_rows
。默认为 True,表示一系列 DELETE 语句应确认游标行数与应匹配的主键数相匹配;这种行为在大多数情况下已被取消(除非使用 version_id),以支持自引用 ON DELETE CASCADE 的不寻常边缘情况;为了适应这一点,消息现在只是一个警告,而不是异常,并且该标志可用于指示期望此类自引用级联删除的映射。有关原始更改的背景,请参见#2403。
参考:#3007 - [ORM] [特性]
如果将MapperEvents.before_configured()
或MapperEvents.after_configured()
事件应用于特定的映射器或映射类,则会发出警告,因为这些事件仅在通用级别的Mapper
目标上调用。 - [ORM] [特性]
向listen()
和listens_for()
添加了一个新的关键字参数once=True
。这是一个方便的功能,它将包装给定的监听器,以便只调用一次。 - [ORM] [特性]
在relationship.innerjoin
中添加了一个新选项,即指定字符串"nested"
。当设置为"nested"
而不是True
时,连接的“链”将在现有外连接的右侧括号内连接内连接,而不是作为一系列外连接的字符串连接。当 0.9 发布时,这可能应该是默认行为,因为我们在 ORM 中引入了右嵌套连接的功能,但是为了避免进一步的意外,我们目前将其保留为非默认行为。
另请参见
右嵌套内连接可用于连接的预加载
参考:#2976 - [orm] [bug]
修复了 ORM 中的一个 bug,即更改对象的主键,然后将其标记为 DELETE 将无法定位正确的行进行 DELETE。
此更改也回溯到:0.8.6
参考:#3006 - [orm] [bug]
修复了从 0.8.3 版本开始的回归问题,这是由于#2818导致的,Query.exists()
在只有一个Query.select_from()
条目但没有其他实体的查询上无法工作。
此更改也回溯到:0.8.6
参考:#2995 - [orm] [bug]
改进了一个错误消息,如果对非可选择的内容进行了查询(例如literal_column()
),然后尝试使用Query.join()
进行连接,使得“左”侧被确定为None
,然后失败。现在明确检测到这种情况。
此更改也回溯到:0.8.6 - [orm] [bug]
从sqlalchemy.orm.interfaces.__all__
中删除了过时的名称,并刷新为当前名称,以便再次从该模块进行import *
操作。
此更改也回溯到:0.8.6
参考:#2975 - [orm] [bug]
修复了一个非常古老的行为,即懒加载在一对多关系中可能会不适当地拉入父表,并且基于父表中的内容返回不一致的结果,当primaryjoin
包含针对父表的某种类型的鉴别器时,例如and_(parent.id == child.parent_id, parent.deleted == False)
。虽然这种primaryjoin
对于一对多关系并没有太多意义,但当应用于多对一的一侧时,这种情况稍微更为常见,并且一对多是作为反向引用的结果。在这种情况下加载child
行会在查询中保留parent.deleted == False
,从而将其拉入FROM
子句并执行笛卡尔积。新行为现在将适当地替换本地的 “parent.deleted” 的值为该参数。尽管通常,一个真实的应用程序可能想在任何情况下都使用不同的primaryjoin
。
参考:#2948 - [orm] [bug]
改进了“如何从 A 连接到 B”的检查,使得当一个表有多个复合外键指向父表时,relationship.foreign_keys
参数将被正确解释以解决歧义;以前,此条件会引发存在多个 FK 路径的错误,而事实上,foreign_keys
参数应该确定哪个路径是预期的。
参考:#2965 - [orm] [bug]
添加了对尚未完全文档化的insert=True
标志与 mapper / 实例事件一起使用的支持。 - [orm] [bug] [engine]
修复了一个 bug,在类级别设置监听事件(例如在Mapper
或ClassManager
级别,而不是在单个映射类上,并且还在Connection
上,也使用了内部参数转换(这在这些类别中是大多数情况)将无法移除。
参考:#2973 - [orm] [bug]
修复了 0.8 中的回归,当使用像lazyload()
这样的选项与“通配符”表达式,例如"*"
,时,在查询中不包含任何实际实体时会引发断言错误。此断言是针对其他情况的,而无意中捕获了这种情况。 - [orm] [bug] [sqlite]
对 SQLite“连接重写”进行了更多修复;在 0.9.3 版本发布之前实施的#2967修复影响了 UNION 中包含嵌套连接的情况。“连接重写”是一个具有广泛可能性的功能,是多年来我们引入的第一个复杂的“SQL 重写”功能,因此我们正在进行许多迭代(有点类似于 0.2/0.3 系列中的急加载,0.4/0.5 中的多态加载)。我们应该很快就会完成,所以感谢您的耐心等待 😃.
参考:#2969
示例
- [示例] [错误]
修复了 versioned_history 示例中的 bug,其中列级别的 INSERT 默认值会阻止写入 NULL 的历史值。
引擎
- [engine] [功能]
为方言级事件添加了一些新的事件机制;初始实现允许事件处理程序重新定义任意方言在 DBAPI 游标上调用 execute()或 executemany()的具体机制。这些新事件,目前是半公开和实验性的,是为了支持即将推出的一些与事务相关的扩展。 - [engine] [功能]
现在可以在创建一个或多个Connection
对象(例如通过 ormSession
或通过显式连接)之后,将事件监听器与Engine
关联,监听器将从这些连接中接收事件。以前,性能问题导致事件传输从Engine
到Connection
仅在初始化时进行,但我们内联了一堆条件检查,使得这一点成为可能,而无需进行任何额外的函数调用。
参考:#2978 - [engine] [错误]
对Engine
在检测到“断开”条件时回收连接池的机制进行了重大改进;不再丢弃池并显式关闭连接,而是保留池并更新“生成”时间戳以反映当前时间,从而在下次检出时回收所有现有连接。这极大地简化了回收过程,消除了等待旧池的“唤醒”连接尝试的需要,并消除了在回收操作期间可能创建许多立即丢弃的“池”对象的竞争条件。
参考:#2985 - [engine] [错误]
ConnectionEvents.after_cursor_execute()
事件现在针对Connection
的“_cursor_execute()”方法发出;这是用于诸如在 INSERT 语句之前执行序列等快速执行器,以及用于方言启动检查(如 unicode 返回、字符集等)的事件。ConnectionEvents.before_cursor_execute()
事件已在此处调用。此处的“executemany”标志现在始终设置为 False,因为此事件始终对应单个执行。以前,如果我们代表 executemany INSERT 语句执行操作,标志可能为 True。
sql
- [sql] [功能]
增加了对布尔值的文字呈现支持,例如“true” / “false”或“1” / “0”。 - [sql] [功能]
增加了一个新功能conv()
,其目的是将约束名称标记为已经应用了命名约定。从 Alembic 0.6.4 开始,Alembic 迁移将使用此标记,在迁移脚本中呈现已经标记为已经受到命名约定影响的约束。 - [sql] [功能]
已增强新的方言级关键字参数系统,以协助依赖于向结构添加临时关键字参数的现有方案。
例如,Index
这样的结构在构造后将再次接受Index.kwargs
集合中的临时关键字参数:
idx = Index("a", "b") idx.kwargs["mysql_someargument"] = True
- 为了适应允许在构造时使用自定义参数的用例,
DialectKWArgs.argument_for()
方法现在允许进行此注册:
Index.argument_for("mysql", "someargument", False) idx = Index("a", "b", mysql_someargument=True)
- 另请参阅
DialectKWArgs.argument_for()
参考:#2866, #2962 - [sql] [错误]
修复了tuple_()
构造中的错误,其中实质上第一个 SQL 表达式的“类型”会被应用为与比较的元组值的“比较类型”;在某些情况下,这会导致不恰当的“类型强制转换”发生,例如当一个混合了 String 和 Binary 值的元组错误地将目标值强制转换为 Binary,即使左侧的值并非如此。tuple_()
现在期望其值列表中存在异构类型。
此更改也已回溯至:0.8.6
参考:#2977 - [sql] [bug]
修复了 0.9 版本中的一个回归问题,即Table
未能正确反映时,即使处于无效状态,也不会从父MetaData
中移除。感谢 Roman Podoliaka 的 Pullreq。
参考:#2988 - [sql] [bug]
MetaData.naming_convention
功能现在还将应用于直接与Column
关联的CheckConstraint
对象,而不仅仅是在Table
上。 - [sql] [bug]
修复了新的MetaData.naming_convention
功能中的错误,其中使用“%(constraint_name)s”标记的检查约束的名称会在布尔或枚举类型生成的约束中重复,整体重复事件会导致“%(constraint_name)s”标记不断累积。
参考:#2991 - [sql] [bug]
调整了将名称应用于.c 集合时的逻辑,当接收到无名称的BindParameter
时,例如通过literal()
或类似方式;绑定参数的“键”被用作.c 中的键,而不是渲染的名称。由于这些绑定在任何情况下都具有“匿名”名称,因此这允许单独的绑定参数在可选择的情况下具有自己的名称,如果它们没有被标记。
参考:#2974 - [sql] [bug]
对FromClause.c
集合的行为进行了一些更改,当出现重复列时。仍然存在发出警告并替换旧列的行为;特别是替换是为了保持向后兼容性。但是,替换的列现在仍然与c
集合关联在一个名为._all_columns
的集合中,该集合由诸如别名和联合之类的结构使用,以处理c
中的列集更加接近实际列列表而不是唯一的键名称。这有助于处理在联合等中使用具有相同名称的 SELECT 语句的情况,以便联合可以按位置匹配列,并且在这里仍然有一些机会使用FromClause.corresponding_column()
(现在它可以返回仅在 selectable.c._all_columns 中的列,而不是其他命名)。新集合下划线的原因是我们仍然需要决定这个列表可能会在哪里结束。理论上它将成为 iter(selectable.c)的结果,但是这意味着迭代的长度将不再与 keys()的长度匹配,需要检查该行为。
参考:#2974 - [sql] [错误]
修复了新的TextClause.columns()
方法中的问题,其中按位置给定的列的排序不会被保留。这可能会在位置相关的情况下产生潜在影响,比如将生成的TextAsFrom
对象应用到联合操作中。
postgresql
- [postgresql] [功能]
为 psycopg2 DBAPI 启用了“合理的多行计数”检查,因为这似乎在 psycopg2 2.0.9 中得到了支持。
此更改还回溯到:0.8.6 - [postgresql] [错误]
修复了由发布 0.8.5 / 0.9.3 的兼容性增强引起的回归,其中索引反射在仅适用于 8.1、8.2 系列的 PostgreSQL 版本上再次中断,周围围绕着永远有问题的 int2vector 类型。虽然 int2vector 自 8.1 起支持数组操作,但显然它只支持从 8.3 开始的 varchar 的 CAST。
此更改还回溯到:0.8.6
参考:#3000
mysql
- [mysql] [错误]
调整了 mysql-connector-python 的设置;在 Py2K 中,“supports unicode statements”标志现在为 False,因此 SQLAlchemy 将在发送到数据库之前将SQL 字符串(注意:不是参数)编码为字节。这似乎允许所有与 mysql-connector 相关的 unicode 测试通过,包括那些使用非 ASCII 表/列名称以及使用 cursor.executemany()下的 unicode 的 TEXT 类型的一些测试。
oracle
- [oracle] [功能]
为 cx_Oracle 方言添加了一个新的引擎选项coerce_to_unicode=True
,该选项恢复了在 Python 2 下的 cx_Oracle 输出类型处理程序方法进行 Unicode 转换的功能,该功能在 0.9.2 中被删除,原因是#2911。一些用例希望对所有字符串值进行 Unicode 强制转换,尽管存在性能问题。拉取请求由 Christoph Zwerschke 提供。
参考:#2911 - [oracle] [bug]
添加了新的数据类型DATE
,它是DateTime
的子类。由于 Oracle 没有“datetime”类型,而只有DATE
,因此在这里,Oracle 方言中的DATE
类型作为DateTime
的实例是合适的。这个问题并不会改变类型的行为,因为数据转换无论如何都由 DBAPI 处理,但是改进的子类布局将有助于检查类型以实现跨数据库兼容性。此外,从 Oracle 方言中删除了大写的DATETIME
,因为这种类型在该上下文中不起作用。
参考:#2987
测试
- [tests] [bug]
修复了一些错误的u''
字符串,这些字符串会导致在 Py3.2 中无法通过测试。补丁由 Arfrever Frehtes Taifersar Arahesis 提供。
参考:#2980
杂项
- [bug] [ext]
修复了可变扩展中的错误以及flag_modified()
中的错误,如果属性已重新分配给自身,则更改事件将不会传播。
此更改也回溯到:0.8.6
参考:#2997 - [bug] [automap] [ext]
为自动映射添加了支持,用于处理在联合继承关系中不应该创建两个类之间关系的情况,对于那些将子类链接回超类的外键。
参考:#3004 - [bug] [pool]
修复了SingletonThreadPool
中的一个小问题,在“清理”过程中,当前要返回的连接可能会在无意中被清除。补丁由 jd23 提供。 - [bug] [ext] [py3k]
修复了关联代理中的错误,其中分配一个空切片(例如x[:] = [...]
)将在 Py3k 上失败。 - [bug] [ext]
修复了由#2810引起的关联代理中的回归问题,导致当从不存在的目标获取标量值时,用户提供的“getter”不再接收None
值。此更改引入的 None 检查现在移至默认 getter 中,因此用户提供的 getter 将再次接收 None 值。
参考:#2810
0.9.3
发布日期:2014 年 2 月 19 日
orm
- [orm] [功能]
添加了新的MapperEvents.before_configured()
事件,允许在configure_mappers()
开始时触发事件,以及在声明中的__declare_first__()
钩子以补充__declare_last__()
。 - [orm] [错误]
修复了Query.get()
在查询存在条件时未能一致引发InvalidRequestError
的错误,当给定的标识已经存在于标识映射中时。
此更改也回溯到:0.8.5
参考:#2951 - [orm] [错误] [sqlite]
修复了 SQLite“连接重写”中的错误,其中 exists()构造的使用未能正确重写,例如当 exists 映射到复杂嵌套连接场景中的 column_property 时。还修复了一个有些相关的问题,即当目标是别名表而不是单独的别名列时,连接重写会在 SELECT 语句的 columns 子句上失败。
参考:#2967 - [orm] [错误]
修复了 0.9 版本中的一个回归问题,即应用于基类(例如具有 propagate=True 标志的声明基类)的 ORM 实例或映射器事件未能应用于由于断言而失败的现有映射类。此外,修复了在删除此类事件时可能发生的属性错误,具体取决于首次分配方式。
参考:#2949 - [orm] [错误]
改进了复合属性的初始化逻辑,使得调用MyClass.attribute
不需要配置映射器步骤已发生,例如,它将正常工作而不会引发任何错误。
参考:#2935 - [orm] [错误]
更多关于[ticket:2932]的问题首次在 0.9.2 中解决,其中使用形式为_
的列键与文本中别名列的匹配仍然无法在 ORM 级别匹配,这最终是由于核心列匹配问题。已添加额外规则,以便在使用TextAsFrom
构造或文字列时考虑列_label
。
参考:#2932
ORM 声明
- [ORM] [声明] [错误]
修复了AbstractConcreteBase
在声明关系配置中无法完全可用的错误,因为其字符串类名在映射器配置时不可用。该类现在显式将自己添加到类注册表中,并且AbstractConcreteBase
以及ConcreteBase
都在configure_mappers()
设置中在配置映射器之前使用新的MapperEvents.before_configured()
事件设置自己。
参考:#2950
示例
- [示例] [特性]
在版本化行示例中添加了可选的“changed”列,以及当版本化的Table
具有显式Table.schema
参数时的支持。感谢 jplaverdure 的拉取请求。
引擎
- [引擎] [错误] [池]
修复了由#2880引起的关键回归,其中新的并发能力从池中返回连接意味着“first_connect”事件现在也不再同步,从而在即使在最小并发情况下也会导致方言配置错误。
此更改也回溯到:0.8.5
参考:#2880, #2964
SQL
- [SQL] [错误]
修复了调用Insert.values()
时传入空列表或元组会引发 IndexError 的错误。现在会生成一个空的插入构造,就像使用空字典一样。
此更改也回溯到:0.8.5
参考文献:#2944 - [sql] [bug]
修复了ColumnOperators.in_()
的 bug,如果错误地传递了包含__getitem__()
方法的列表达式的比较器,例如使用ARRAY
类型的列,将进入无限循环。
这个改变也被回溯到:0.8.5
参考文献:#2957 - [sql] [bug]
修复了新“命名约定”功能中的回归,在外键中的引用表包含模式名称时会导致约定失败的问题。感谢 Thomas Farvour 提供的拉取请求。 - [sql] [bug]
修复了所谓的“字面渲染”bindparam()
构造的 bug,如果绑定是用可调用对象而不是直接值构造的,则会失败。这阻止了 ORM 表达式使用“literal_binds”编译器标志进行渲染。
postgresql
- [postgresql] [feature]
在ARRAY
类型上添加了TypeEngine.python_type
方便访问器。感谢 Alexey Terentev 提供的拉取请求。 - [postgresql] [bug]
向 psycopg2 断开连接检测添加了一个额外的消息,“无法发送数据到服务器”,这补充了现有的“无法从服务器接收数据”的消息,已被用户观察到。
这个改变也被回溯到:0.8.5
参考文献:#2936 - [postgresql] [bug]
改进了对非常旧(8.1 版本之前)版本的 PostgreSQL 以及可能的其他 PG 引擎(假设 Redshift 报告的版本 < 8.1)的 PostgreSQL 反射行为的支持。关于“索引”以及“主键”的查询依赖于检查所谓的“int2vector”数据类型,该类型在 8.1 之前拒绝强制转换为数组,导致查询中使用的“ANY()”运算符失败。通过广泛搜索,找到了一个非常糟糕但是被 PG 核心开发者推荐使用的查询,用于当 PG 版本 < 8.1 时,索引和主键约束反射现在可以在这些版本上正常工作。
- 这个改变也被回溯到:0.8.5
- [postgresql] [bug]
修订了这个非常古老的问题,其中 PostgreSQL 的“获取主键”反射查询已更新,以考虑重命名的主键约束;新的查询在非常旧的 PostgreSQL 版本(如版本 7)上失败,因此在检测到 server_version_info < (8, 0) 的情况下,在这些情况下恢复旧的查询。
这个改变也被回溯到:0.8.5
参考:#2291 - [postgresql] [bug]
对于新添加的方言启动查询“show standard_conforming_strings”添加了服务器版本检测;由于此变量是从 PG 8.2 版本开始添加的,我们会跳过对于报告早于该版本的 PG 版本的查询。
参考:#2946
mysql
- [mysql] [feature]
添加了新的 MySQL 特定的DATETIME
,其中包括分数秒的支持;还为TIMESTAMP
添加了分数秒的支持。尽管 DBAPI 支持有限,但 MySQL Connector/Python 已知支持分数秒。补丁由 Geert JM Vanderkelen 提供。
此更改也被回溯到:0.8.5
参考:#2941 - [mysql] [bug]
添加了对PARTITION BY
和PARTITIONS
MySQL 表关键字的支持,指定为mysql_partition_by='value'
和mysql_partitions='value'
到Table
。感谢 Marcus McCurdy 的拉取请求。
此更改也被回溯到:0.8.5
参考:#2966 - [mysql] [bug]
修复了一个 bug,该 bug 阻止了基于 MySQLdb 的方言(例如 pymysql)在 Py3K 中工作,因为“connection charset”的检查会由于 Py3K 更严格的值比较规则而失败。在这种情况下,所调用的方法根本没有考虑数据库版本,因为服务器版本在那时仍然为 None,因此该方法已经简化为依赖于 connection.character_set_name()。
此更改也被回溯到:0.8.5
参考:#2933 - [mysql] [bug] [cymysql]
修复了 cymysql 方言中的一个 bug,即像'33a-MariaDB'
这样的版本字符串无法正确解析。感谢 Matt Schmidt 的拉取请求。
参考:#2934
sqlite
- [sqlite] [bug]
SQLite 方言现在在反射类型时将跳过不支持的参数;例如,如果遇到像INTEGER(5)
这样的字符串,将实例化INTEGER
类型而不包含“5”,基于在第一次尝试时检测到TypeError
。 - [sqlite] [bug]
对 SQLite 类型反射添加了对完全支持在www.sqlite.org/datatype3.html
指定的“类型亲和性”协议的支持。在这个方案中,类型名称中的关键字如INT
、CHAR
、BLOB
或REAL
通常将类型与五种亲和性之一关联起来。感谢 Erich Blume 的拉取请求。
另请参阅
类型反射
杂项
- [bug] [ext]
修复了新 automap 扩展的AutomapBase
类在类被预先排列在单个或潜在的连接继承模式中时会失败的错误。修复的连接继承问题也可能在使用DeferredReflection
时应用。
orm
- [orm] [feature]
添加了新的MapperEvents.before_configured()
事件,允许在configure_mappers()
开始时触发事件,以及在声明性中补充__declare_last__()
的__declare_first__()
钩子。 - [orm] [bug]
修复了Query.get()
在查询中存在现有条件时无法一致引发InvalidRequestError
的错误,当给定的标识已经存在于标识映射中时。
此更改也回溯到:0.8.5
参考:#2951 - [orm] [bug] [sqlite]
修复了 SQLite“连接重写”中的错误,其中 exists()构造的使用未能正确重写,例如,当 exists 映射到复杂嵌套连接场景中的 column_property 时。还修复了一个有些相关的问题,即当目标是别名表而不是单独的别名列时,连接重写会在 SELECT 语句的 columns 子句上失败。
参考:#2967 - [orm] [bug]
修复了 0.9 版本中的一个回归,即应用于基类(例如具有 propagate=True 标志的声明性基类)的 ORM 实例或映射器事件将无法应用于已存在的使用继承的映射类,因为断言失败。此外,修复了在删除此类事件时可能发生的属性错误,具体取决于首次分配方式。
参考:#2949 - [orm] [bug]
改进了复合属性的初始化逻辑,使调用MyClass.attribute
不需要配置映射器步骤,例如,它将正常工作而不会抛出任何错误。
参考:#2935 - [orm] [bug]
在 0.9.2 中首次解决的更多问题,其中使用形式为_
的列键与文本中的别名列匹配仍然不会在 ORM 级别匹配,这最终是由于核心列匹配问题。已添加额外规则,以便在使用TextAsFrom
构造或文字列时考虑列_label
。
参考:#2932
orm 声明式
- [orm] [declarative] [bug]
修复了AbstractConcreteBase
在声明关系配置中无法完全可用的错误,因为其字符串类名在映射器配置时不可用。该类现在明确将自己添加到类注册表中,并且AbstractConcreteBase
以及ConcreteBase
在映射器配置之前之前设置自己,在configure_mappers()
设置中,使用新的MapperEvents.before_configured()
事件。
参考:#2950
示例
- [examples] [feature]
在版本化行示例中添加了可选的“changed”列,以及当版本化Table
具有显式Table.schema
参数时的支持。拉取��求由 jplaverdure 提供。
引擎
- [engine] [bug] [pool]
修复了由#2880引起的关键回归,其中新的并发能力从池中返回连接意味着“first_connect”事件现在也不再同步,从而在即使是最小并发情况下也会导致方言配置错误。
此更改也回溯到:0.8.5
参考:#2880,#2964
sql
- [sql] [bug]
修复了调用带有空列表或元组的Insert.values()
会引发 IndexError 的错误。现在它会生成一个空的插入构造,就像使用空字典的情况一样。
此更改也回溯到:0.8.5
参考:#2944 - [sql] [bug]
修复了ColumnOperators.in_()
会陷入无限循环的错误,如果错误地传递了一个包含__getitem__()
方法的列表达式的比较器,比如一个使用ARRAY
类型的列。
这个变更也被回溯到:0.8.5
参考:#2957 - [sql] [bug]
修复了新“命名约定”功能中的回归错误,在外键中引用的表包含模式名称时,约定会失败。感谢 Thomas Farvour 的拉取请求。 - [sql] [bug]
修复了所谓的bindparam()
构造的“字面渲染”失败的错误,如果绑定是用可调用方式构造的,而不是直接值。这会阻止 ORM 表达式使用“literal_binds”编译器标志进行渲染。
postgresql
- [postgresql] [feature]
在ARRAY
类型上添加了TypeEngine.python_type
的便利访问器。感谢 Alexey Terentev 的拉取请求。 - [postgresql] [bug]
添加了对 psycopg2 断开连接检测的额外消息,“无法发送数据到服务器”,这补充了现有的“无法从服务器接收数据”并被用户观察到。
这个变更也被回溯到:0.8.5
参考:#2936 - [postgresql] [bug]
对于非常旧的(8.1 之前)PostgreSQL 版本以及可能的其他 PG 引擎(假设 Redshift 报告的版本为 < 8.1),改进了对 PostgreSQL 反射行为的支持。关于“索引”和“主键”的查询依赖于检查所谓的“int2vector”数据类型,它在 8.1 之前拒绝强制转换为数组,导致查询中使用的“ANY()”运算符失败。通过广泛的搜索,找到了非常笨拙但由 PG 核心开发人员推荐使用的查询,用于当 PG 版本 < 8.1 时,索引和主键约束反射现在在这些版本上工作。
- 这个变更也被回溯到:0.8.5
- [postgresql] [bug]
修正了这个非常古老的问题,即 PostgreSQL “获取主键”反射查询已更新以考虑已重命名的主键约束;新的查询在旧版本的 PostgreSQL 中(如版本 7)失败,因此在检测到 server_version_info < (8, 0) 时,恢复了旧的查询。
这个变更也被回溯到:0.8.5
参考:#2291 - [postgresql] [bug]
在新添加的方言启动查询中添加了服务器版本检测,用于“show standard_conforming_strings”;由于此变量是从 PG 8.2 开始添加的,我们会跳过报告版本字符串早于此的 PG 版本的查询。
参考:#2946
mysql
- [mysql] [feature]
添加了新的 MySQL 特定的DATETIME
,其中包括分数秒支持;还为TIMESTAMP
添加了分数秒支持。尽管 DBAPI 支持有限,但分数秒已知受到 MySQL Connector/Python 的支持。补丁由 Geert JM Vanderkelen 提供。
此更改也被回溯到:0.8.5
参考:#2941 - [mysql] [bug]
添加了对PARTITION BY
和PARTITIONS
MySQL 表关键字的支持,指定为mysql_partition_by='value'
和mysql_partitions='value'
到Table
。拉取请求由 Marcus McCurdy 提供。
此更改也被回溯到:0.8.5
参考:#2966 - [mysql] [bug]
修复了阻止基于 MySQLdb 的方言(例如 pymysql)在 Py3K 中工作的错误,其中“连接字符集”检查会由于 Py3K 更严格的值比较规则而失败。在任何情况下,所涉及的调用都没有考虑数据库版本,因为服务器版本在那时仍然为 None,因此该方法已经简化为依赖于 connection.character_set_name()。
此更改也被回溯到:0.8.5
参考:#2933 - [mysql] [bug] [cymysql]
修复了 cymysql 方言中的错误,其中版本字符串如'33a-MariaDB'
无法��确解析。拉取请求由 Matt Schmidt 提供。
参考:#2934
sqlite
- [sqlite] [bug]
SQLite 方言现在在反射类型时会跳过不支持的参数;例如,如果遇到类似INTEGER(5)
的字符串,INTEGER
类型将在实例化时不包含“5”,基于在第一次尝试时检测到TypeError
。 - [sqlite] [bug]
已添加对 SQLite 类型反射的支持,以完全支持在www.sqlite.org/datatype3.html
中指定的“类型亲和性”协议。在此方案中,类型名称中的关键字如INT
、CHAR
、BLOB
或REAL
通常将类型与五种亲和性之一关联起来。拉取请求由 Erich Blume 提供。
另请参阅
类型反射
杂项
- [bug] [ext]
修复了新自动映射扩展的AutomapBase
类在类被预先排列在单个或潜在的联合继承模式中时会失败的错误。修复的联合继承问题也可能适用于使用DeferredReflection
时。
0.9.2
发布日期:2014 年 2 月 2 日
orm
- [orm] [feature]
添加了一个新参数Operators.op.is_comparison
。此标志允许来自Operators.op()
的自定义操作被视为“比较”运算符,因此可用于自定义relationship.primaryjoin
条件。
另请参阅
在连接条件中使用自定义操作符 - [orm] [feature]
改进了为relationship.secondary
的目标提供join()
构造的支持,以便创建非常复杂的relationship()
连接条件。此更改包括对查询连接、连接的急加载进行调整,以避免渲染 SELECT 子查询,对延迟加载进行更改,以便正确包含“次要”目标在 SELECT 中,并对声明性进行更改以更好地支持将 join()对象与类作为目标的规范。
新用例有些实验性,但已添加了新的文档部分。
另请参阅
复合“次要”连接 - [orm] [bug]
修复了当将迭代器对象传递给class_mapper()
或类似函数时出现的错误消息,该错误会导致字符串格式化时无法呈现错误。感谢 Kyle Stark 提交的 Pullreq。
此更改也回溯至:0.8.5 - [orm] [bug]
在新的TextAsFrom
结构中修复了一个错误,其中Column
导向的行查找与TextAsFrom
生成的临时ColumnClause
对象不匹配,因此在Query.from_statement()
中无法使用。还修复了Query.from_statement()
的机制,以防将TextAsFrom
错误地误认为是Select
构造。此错误也是 0.9 的回归,因为需要调用TextClause.columns()
方法来适应text.typemap
参数。
引用:#2932 - [orm] [bug]
在属性“set”操作范围内添加了一个新指令,用于禁用自动刷新,在属性需要延迟加载“旧”值的情况下使用,例如替换一对一值或某些类型的一对多值。在此时刷新否则会在属性为 None 时发生,并可能导致 NULL 违规。
引用:#2921 - [orm] [bug]
修复了 0.9 中的一个回归,即Query
自动别名和在其他情况下别名(例如联接表继承)可能会失败,如果表达式中使用了用户定义的Column
子类。在这种情况下,子类将无法传播 ORM 特定的“注解”,这些注解由适配器所需。已对“表达式注解”系统进行了修正,以解决此问题。
引用:#2918 - [orm] [bug]
修复了一个关于新的扁平化 JOIN 结构的错误,该结构与joinedload()
一起使用(从而导致连接贪婪加载中的回归),以及与flat=True
标志和联接表继承一起使用的aliased()
;基本上,通过不同路径跨越“父 JOIN 子”实体进行多次连接以到达目标类的多个连接不会形成正确的 ON 条件。在处理 aliased、joined-inh 类的“左侧”连接的机制中进行了调整/简化,修复了此问题。
参考:#2908
示例
- [示例] [错误]
对“history_meta”示例进行了微调,现在在关系绑定属性上检查“history”时,如果关系未加载,则不会再发出任何 SQL。
引擎
- [引擎] [特性] [池]
添加了一个新的池事件PoolEvents.invalidate()
。当要将 DBAPI 连接标记为“无效”并从池中丢弃时调用。
sql
- [sql] [特性]
添加了MetaData.reflect.dialect_kwargs
,以支持为所有反射的Table
对象设置方言级别的反射选项。 - [sql] [特性]
添加了一个新功能,允许自动命名约定应用于Constraint
和Index
对象。基于维基中的一个示例,新功能使用模式事件来设置名称,因为各种模式对象相互关联。然后,事件通过一个新参数MetaData.naming_convention
公开一个配置系统。该系统允许在每个MetaData
基础上生成简单和自定义的约束和索引命名方案。
另请参阅
配置约束命名约定
参考:#2923 - [sql] [特性]
现在可以在PrimaryKeyConstraint
对象上独立于使用primary_key=True
标志在表中指定列的情况下指定选项;使用一个不包含列的PrimaryKeyConstraint
对象即可实现此结果。
以前,显式的PrimaryKeyConstraint
会导致将标记为primary_key=True
的列被忽略;由于不再这样,PrimaryKeyConstraint
现在将断言使用其中一种样式来指定列,或者如果两者都存在,则列列表必须完全匹配。如果在PrimaryKeyConstraint
和在Table
中标记为primary_key=True
的不一致列集存在,则会发出警告,并且列列表仅从PrimaryKeyConstraint
中获取,就像在先前的版本中一样。
另请参阅PrimaryKeyConstraint
参考:#2910 - [sql] [feature]
架构构造和某些 SQL 构造接受特定方言关键字参数的系统已得到增强。这个系统通常包括Table
和Index
构造,它们接受各种各样的特定方言参数,如mysql_engine
和postgresql_where
,以及构造PrimaryKeyConstraint
、UniqueConstraint
、Update
、Insert
和Delete
,还新增了对ForeignKeyConstraint
和ForeignKey
的关键字参数功能。改变在于参与的方言现在可以为这些构造指定可接受的参数列表,允许在为特定方言指定无效关键字时引发参数错误。如果关键字的方言部分未被识别,只会发出警告;虽然系统实际上会利用 setuptools 入口点来定位非本地方言,但在未安装第三方方言的环境中使用某些特定方言参数的用例仍然受支持。方言还必须明确选择加入这个系统,因此不使用这个系统的外部方言将不受影响。
参考:#2866 - [sql] [bug]
Table.tometadata()
的行为已经调整,以便当ForeignKey
的模式目标不匹配父表的模式时,不会更改。也就是说,如果一个表“schema_a.user”有一个指向“schema_b.order.id”的外键,无论是否将“schema”参数传递给Table.tometadata()
,都将保持“schema_b”目标。但是,如果一个表“schema_a.user”引用“schema_a.order.id”,则“schema_a”将在父表和被引用表上更新。这是一个行为变更,因此不太可能被回溯到 0.8;可以假设以前的行为相当错误,而且很少有人依赖它。
另外,新增了一个参数Table.tometadata.referred_schema_fn
。这是一个可调用函数,用于确定在 tometadata 操作中遇到的任何ForeignKeyConstraint
的新引用模式。这个可调用函数可以用于恢复到以前的行为,或者根据每个约束自定义如何处理引用模式。
参考:#2913 - [sql] [bug]
修复了在某些情况下,如果与“test”方言(例如 DefaultDialect 或其他没有 DBAPI 的方言)一起使用二进制类型会失败的 bug。 - [sql] [bug] [py3k]
修复了“literal binds”无法与绑定参数是二进制类型的 bug。在 0.8 中修复了类似但不同的问题。 - [sql] [bug]
修复了 ORM 使用的“注释”系统泄漏到sqlalchemy.sql.functions
中标准函数(如func.coalesce()
和func.max()
)使用的名称中的回归问题。在 ORM 属性中使用这些函数,从而生成它们的带注释版本,可能会破坏在 SQL 中呈现的实际函数名称。
参考:#2927 - [sql] [bug]
修复了 0.9 版本中新的RowProxy
可排序支持导致与非元组类型比较时会导致TypeError
的回归问题,因为它试图无条件地应用 tuple()到“other”对象。现在在RowProxy
上实现了完整的 Python 比较运算符范围,使用一种保证等效于元组的比较系统的方法,只有在“other”对象是 RowProxy 的实例时才会强制转换。
参考:#2848, #2924 - [sql] [bug]
与一个没有列的Table
内联创建的UniqueConstraint
将被跳过。Pullreq 由 Derek Harland 提供。 - [sql] [bug] [orm]
修复了多表“UPDATE…FROM”构造,在 MySQL 上可用,以正确地在跨表中的多个相同名称的列之间渲染 SET 子句。这也将非主表中用于 SET 子句中的绑定参数的名称更改为“_”;由于通常直接使用Column
对象指定此参数,这不应对应用程序产生影响。此修复对 ORM 中的Table.update()
和Query.update()
都生效。
参考:#2912
schema
- [schema] [bug]
将sqlalchemy.schema.SchemaVisitor
恢复到.schema
模块中。Pullreq 由 Sean Dague 提供。
postgresql
- [postgresql] [feature]
添加了一个新的方言级参数postgresql_ignore_search_path
;该参数被Table
构造函数和MetaData.reflect()
方法都接受。当用于 PostgreSQL 时,指定了远程模式名称的外键引用表将保留该模式名称,即使该名称存在于search_path
中;自 0.7.3 以来的默认行为是,search_path
中存在的模式不会复制到反射的ForeignKey
对象中。文档已更新以详细描述pg_get_constraintdef()
函数的行为以及postgresql_ignore_search_path
特性如何实质上决定我们是否会尊重此函数报告的模式资格。
另见
远程模式表内省和 PostgreSQL search_path
参考:#2922
mysql
- [mysql] [bug]
为 cymysql 方言添加了一些缺失的方法,包括 _get_server_version_info() 和 _detect_charset()。Pullreq 由 Hajime Nakagami 提供。
此更改也被 回溯 到:0.8.5 - [mysql] [bug] [sql]
为所谓的 SQL 类型的“向下适应”添加了新的测试覆盖,其中更具体的类型被适应为更通用的类型 - 这种用例被一些第三方工具(如sqlacodegen
)所需。在此测试套件中需要修复的特定情况是将ENUM
降级为Enum
,以及将 SQLite 日期类型转换为通用日期类型。adapt()
方法需要在这里变得更具体,以抵消在 0.9 中删除的基本TypeEngine
类上的“捕获所有”**kwargs
集合的移除。
参考:#2917 - [mysql] [bug]
现在 MySQL CAST 编译考虑了字符串类型的“字符集”和“排序”。虽然 MySQL 希望所有基于字符的 CAST 调用都使用 CHAR 类型,但我们现在在 CAST 时创建一个真正的 CHAR 对象,并复制它具有的所有参数,因此像cast(x, mysql.TEXT(charset='utf8'))
这样的表达式将呈现为CAST(t.col AS CHAR CHARACTER SET utf8)
。 - [mysql] [bug]
对 MySQL 方言和整体默认方言系统添加了新的“unicode 返回”检测,以便任何方言都可以在首次连接时添加额外的“测试”来检测 DBAPI 是否直接返回 unicode。在这种情况下,我们特别针对“utf8”编码添加了一个检查,使用显式的“utf8_bin”排序类型(在检查此排序是否可用后)来测试观察到的 MySQLdb 版本 1.2.3 存在的一些错误的 unicode 行为。虽然 MySQLdb 在 1.2.4 中已解决了此问题,但此处的检查应该防止出现退化。此更改还允许“unicode”检查记录在引擎日志中,这以前是不可能的。
参考:#2906 - [mysql] [bug] [engine] [pool]
Connection
现在将一个新的RootTransaction
或TwoPhaseTransaction
与其立即的_ConnectionFairy
关联为该事务的“复位处理程序”,在该事务的范围内接管调用 commit() 或 rollback() 来处理Pool
的“返回时重置”行为,如果事务没有被其他方式完成。这解决了当连接关闭时,像 MySQL 两阶段那样挑剔的事务将被正确关闭的问题,而不需要显式的回滚或提交(例如,在此情况下不再引发“XAER_RMFAIL” - 请注意,这仅显示在日志中,因为异常未在池重置中传播)。例如,当使用带有twophase
设置的 ormSession
,然后在没有显式回滚或提交的情况下调用Session.close()
时,会出现此问题。该更改还具有的效果是,现在在非自动提交模式下使用Session
对象时,无论该会话是如何被丢弃的,都会在日志中看到显式的“ROLLBACK”。感谢 Jeff Dairiki 和 Laurence Rowe 在此处隔离问题。
参考资料:#2907
sqlite
- [sqlite] [bug]
修复了一个错误,即 SQLite 编译器无法将编译器参数(例如“literal binds”)传播到 CAST 表达式中的情况。
mssql
- [mssql] [feature]
向UniqueConstraint
和PrimaryKeyConstraint
构造添加了一个选项mssql_clustered
;在 SQL Server 上,这将在 DDL 中将CLUSTERED
关键字添加到约束构造中。感谢 Derek Harland 提供了 Pullreq。
oracle
- [oracle] [bug]
已经观察到,在 Python 2.xx 中使用 cx_Oracle 的 “outputtypehandler” 来将字符串值强制转换为 Unicode 是非常昂贵的;即使 cx_Oracle 是用 C 编写的,当你将 Pythonunicode
原语传递给 cursor.var() 并与输出处理程序关联时,库会将每次转换都记录为 Python 函数调用,带有所有必要的开销;尽管在 Python 3 中运行时,所有字符串也被无条件地强制转换为 unicode,但它不会产生这种开销,这意味着 cx_Oracle 在 Py2K 中未能使用高效的技术。由于 SQLAlchemy 无法轻松地按列选择这种类型处理程序,因此处理程序是无条件地组装的,从而为所有字符串访问添加了开销。
因此,这个逻辑已被替换为 SQLAlchemy 自己的 unicode 转换系统,现在只在请求为 unicode 的列中对 Py2K 生效。当使用 C 扩展时,SQLAlchemy 的系统似乎比 cx_Oracle 的快 2-3 倍。此外,SQLAlchemy 的 unicode 转换已经得到增强,以便在需要“条件”转换器(现在需要用于 Oracle 后端)时,在 C 中执行“已经是 unicode”的检查,不再引入显著的开销。
这个变化对 cx_Oracle 后端有两个影响。一个是在 Py2K 中,未明确请求 Unicode 类型或 convert_unicode=True 的字符串值现在将返回为str
,而不是unicode
- 这种行为类似于像 MySQL 这样的后端。此外,当使用 cx_Oracle 后端请求 unicode 值时,如果不使用 C 扩展,则现在每列都会有一个 isinstance() 检查的额外开销。这种权衡已经做出,因为它可以被解决,并且不再对大多数非 unicode 字符串的 Oracle 结果列产生性能负担。
参考:#2911
杂项
- [bug] [pool]
PoolEvents.reset()
事件的参数名称已更改为dbapi_connection
和connection_record
,以保持与所有其他池事件的一致性。预计任何现有监听器对于这个相对较新且很少使用的事件都是使用位置样式来接收参数。 - [bug] [cextensions] [py3k]
修复了一个问题,即 Py3K 中的 C 扩展正在使用错误的 API 来指定顶级模块函数,这在 Python 3.4b2 中会出错。Py3.4b2 将 PyMODINIT_FUNC 更改为返回“void”,而不是PyObject *
,因此我们现在确保直接使用“PyMODINIT_FUNC”而不是PyObject *
。感谢 cgohlke 提交的拉取请求。
orm
- [orm] [feature]
添加了一个新参数Operators.op.is_comparison
。此标志允许从Operators.op()
中选择自定义运算符作为“比较”运算符,因此可用于自定义relationship.primaryjoin
条件。
另请参阅
在连接条件中使用自定义运算符 - [orm] [feature]
改进了将join()
构造作为relationship.secondary
的目标以创建非常复杂的relationship()
连接条件的支持。该更改包括对查询连接、连接的急加载进行调整,以避免渲染 SELECT 子查询,对延迟加载进行更改,以便正确地在 SELECT 中包含“次要”目标,并对声明性进行更改以更好地支持使用类作为目标的 join() 对象的规范。
新的用例有些实验性,但已添加了新的文档部分。
另请参阅
复合“次要”连接 - [orm] [bug]
修复了当将迭代器对象传递给class_mapper()
或类似方法时出现的错误消息,该错误会导致字符串格式化时无法呈现。感谢 Kyle Stark 提交的 Pullreq。
此更改也已回溯至:0.8.5 - [orm] [bug]
修复了新的TextAsFrom
构造中的错误,其中Column
- 导向行查找未与TextAsFrom
生成的临时ColumnClause
对象相匹配,因此不能在Query.from_statement()
中使用。同时修复了Query.from_statement()
机制,以免将TextAsFrom
错误地视为Select
构造。该错误也是 0.9 的一个回归,因为要适应text.typemap
参数,TextClause.columns()
方法被调用。
参考:#2932 - [orm] [bug]
添加了一个新的指令,在属性“设置”操作的范围内使用,以禁用自动刷新,在属性需要惰性加载“旧”值的情况下使用,例如替换一对一值或某些类型的一对多。此时刷新通常在属性为 None 时发生,并且可能会导致 NULL 违规。
参考:#2921 - [orm] [bug]
修复了 0.9 版本中的一个回归,即Query
自动别名化以及在其他情况下选择或连接被别名化(例如连接表继承)可能会失败,如果表达式中使用了用户定义的Column
子类。在这种情况下,子类将无法传播需要适应的 ORM 特定的“注解”。已经修正了“表达式注解”系统以解决此问题。
参考:#2918 - [orm] [bug]
修复了一个关于新的扁平化 JOIN 结构的错误,该结构与joinedload()
(从而导致连接贪婪加载的回归)以及与flat=True
标志和联接表继承一起使用的aliased()
相关的错误;基本上,通过不同路径跨越“父 JOIN 子”实体进行多次连接以到达目标类的多个连接不会形成正确的 ON 条件。在处理 aliased、joined-inh 类的“左侧”连接的机制中进行了调整/简化,修复了这个问题。
参考:#2908
例子
- [examples] [bug]
对“history_meta”示例进行了调整,当关系绑定属性上的“history”检查不再发出任何 SQL 时,如果关系未加载。
engine
- [engine] [feature] [pool]
添加了一个新的池事件PoolEvents.invalidate()
。当一个 DBAPI 连接被标记为“无效”并且从池中丢弃时调用。
sql
- [sql] [feature]
添加了MetaData.reflect.dialect_kwargs
以支持为所有反射的Table
对象设置方言级别的反射选项。 - [sql] [feature]
添加了一个新功能,允许自动命名约定应用于Constraint
和Index
对象。基于维基百科中的一个配方,新功能使用模式事件来设置名称,当各种模式对象相互关联时。然后,事件通过一个新参数MetaData.naming_convention
暴露一个配置系统。该系统允许在每个MetaData
基础上生成简单和自定义的约束和索引命名方案。
另请参阅
配置约束命名约定
参考:#2923 - [sql] [feature]
现在可以在PrimaryKeyConstraint
对象上独立指定选项,而不需要在表中的列上使用primary_key=True
标志;使用一个不包含列的PrimaryKeyConstraint
对象即可实现此目的。
以前,显式的PrimaryKeyConstraint
会导致那些标记为primary_key=True
的列被忽略;由于现在不再这样,PrimaryKeyConstraint
现在会断言要么使用一种风格指定列,要么使用另一种风格,或者如果两者都存在,则列列表必须完全匹配。如果在PrimaryKeyConstraint
和在Table
中标记为primary_key=True
的不一致列集存在,则会发出警告,并且列列表仅从PrimaryKeyConstraint
中获取,就像在先前的版本中一样。
另请参阅PrimaryKeyConstraint
参考:#2910 - [sql] [feature]
架构构造和某些 SQL 构造接受特定方言的关键字参数的系统已经得到增强。这个系统通常包括Table
和Index
构造,它们接受各种特定方言的参数,比如mysql_engine
和postgresql_where
,以及PrimaryKeyConstraint
、UniqueConstraint
、Update
、Insert
和Delete
等构造,还新增了对ForeignKeyConstraint
和ForeignKey
的关键字参数功能。改变之处在于参与的方言现在可以为这些构造指定可接受的参数列表,允许在为特定方言指定无效关键字时引发参数错误。如果关键字的方言部分未被识别,只会发出警告;虽然系统实际上会利用 setuptools 的 entrypoints 来定位非本地方言,但在未安装第三方方言的环境中使用某些特定方言参数的用例仍然受支持。方言还必须明确选择加入这个系统,因此不使用这个系统的外部方言将不受影响。
参考:#2866 - [sql] [bug]
Table.tometadata()
的行为已经调整,以便在不匹配父表模式的情况下不会更改ForeignKey
的模式目标。也就是说,如果一个表“schema_a.user”有一个指向“schema_b.order.id”的外键,无论是否将“schema”参数传递给Table.tometadata()
,都将保持“schema_b”目标。但是,如果一个表“schema_a.user”引用“schema_a.order.id”,则“schema_a”将在父表和引用表上更新。这是一个行为变更,因此不太可能被回溯到 0.8;可以假设以前的行为相当错误,而且很少有人依赖它。
另外,新增了一个参数Table.tometadata.referred_schema_fn
。这是一个可调用函数,用于确定在 tometadata 操作中遇到的任何ForeignKeyConstraint
的新引用模式。这个可调用函数可以用于恢复到以前的行为或者自定义如何处理每个约束的引用模式。
参考:#2913 - [sql] [bug]
修复了二进制类型在某些情况下与“test”方言(例如 DefaultDialect 或其他没有 DBAPI 的方言)一起使用时会失败的 bug。 - [sql] [bug] [py3k]
修复了“literal binds”无法与绑定参数为二进制类型的 bug。0.8 中修复了类似但不同的问题。 - [sql] [bug]
修复了 ORM 使用的“注释”系统泄漏到sqlalchemy.sql.functions
中标准函数(如func.coalesce()
和func.max()
)使用的名称中的回归问题。在 ORM 属性中使用这些函数,从而生成它们的带注释版本,可能会破坏在 SQL 中呈现的实际函数名称。
参考:#2927 - [sql] [bug]
修复了 0.9 中的回归问题,新的RowProxy
可排序支持会导致与非元组类型比较时引发TypeError
,因为它试图无条件地应用 tuple()到��other”对象。现在在RowProxy
上实现了完整的 Python 比较运算符范围,使用一种保证等效于元组的比较系统的方法,只有当“other”对象是RowProxy
的实例时才会强制转换。
参考:#2848, #2924 - [sql] [bug]
在没有列的Table
中内联创建的UniqueConstraint
将被跳过。Pullreq 感谢 Derek Harland。 - [sql] [bug] [orm]
修复了多表“UPDATE…FROM”结构,仅适用于 MySQL,在多个表中正确呈现 SET 子句的问题。这也更改了 SET 子句中用于非主表的绑定参数的名称为“_”;由于该参数通常是直接使用Column
对象指定的,因此这不会对应用程序产生影响。此修复对 ORM 中的Table.update()
和Query.update()
都生效。
参考:#2912
schema
- [schema] [bug]
恢复了sqlalchemy.schema.SchemaVisitor
到.schema
模块。Pullreq 感谢 Sean Dague。
postgresql
- [postgresql] [feature]
新增了一个方言级别的参数postgresql_ignore_search_path
;该参数被Table
构造函数和MetaData.reflect()
方法同时接受。在针对 PostgreSQL 使用时,如果外键引用的表指定了远程模式名称,即使该名称存在于search_path
中,也会保留该模式名称;自 0.7.3 以来的默认行为是,search_path
中存在的模式不会被复制到反映的ForeignKey
对象中。文档已经更新,详细描述了pg_get_constraintdef()
函数的行为以及postgresql_ignore_search_path
特性如何确定我们是否会尊重此函数报告的模式限定。
另请参阅
远程模式表内省和 PostgreSQL search_path
参考:#2922
mysql
- [mysql] [bug]
向 cymysql 方言添加了一些缺失的方法,包括 _get_server_version_info() 和 _detect_charset()。Pullreq 感谢 Hajime Nakagami。
此更改也已回溯至:0.8.5 - [mysql] [bug] [sql]
为所谓的 SQL 类型的“向下适配”添加了新的测试覆盖,其中更具体的类型被适配为更通用的类型 - 这种用例被一些第三方工具(如sqlacodegen
)所需。在这个测试套件中需要修复的具体情况包括将ENUM
转换为Enum
,以及将 SQLite 日期类型转换为通用日期类型。adapt()
方法在这里需要变得更具体,以抵消在 0.9 版本中从基本TypeEngine
类中删除的“捕获所有”**kwargs
集合。
参考:#2917 - [mysql] [bug]
MySQL CAST 编译现在考虑了字符串类型的“字符集”和“校对规则”等方面。虽然 MySQL 希望所有基于字符的 CAST 调用都使用 CHAR 类型,但我们现在在 CAST 时创建一个真正的 CHAR 对象,并复制它所有的参数,因此像cast(x, mysql.TEXT(charset='utf8'))
这样的表达式将会渲染为CAST(t.col AS CHAR CHARACTER SET utf8)
。 - [mysql] [bug]
向 MySQL 方言和默认方言系统整体添加了新的“unicode 返回”检测,以便任何方言都可以向首次连接时添加额外的“测试”来检测“这个 DBAPI 是否直接返回 unicode”。在这种情况下,我们特别针对“utf8”编码添加了一个检查,带有显式的“utf8_bin”校对类型(在检查此校对是否可用后),以测试观察到的 MySQLdb 版本 1.2.3 存在的一些错误的 unicode 行为。虽然 MySQLdb 已在 1.2.4 版本中解决了这个问题,但这里的检查应该防范回归。此更改还允许“unicode”检查记录在引擎日志中,这在以前是不可能的。
参考:#2906 - [mysql] [bug] [engine] [pool]
Connection
现在将一个新的RootTransaction
或TwoPhaseTransaction
与其直接的_ConnectionFairy
关联为该事务的“重置处理程序”,负责在事务期间调用 commit() 或 rollback() 以实现Pool
的“返回时重置”行为,如果事务未被其他方式完成,则接管该任务。当连接关闭而没有显式的回滚或提交时,解决了像 MySQL 两阶段这样挑剔的事务将被正确关闭的问题(例如,在此情况下不再引发“XAER_RMFAIL” - 请注意,这只会显示在日志中,因为异常不会在池重置中传播)。当使用设置了twophase
的 ormSession
,然后在没有显式的回滚或提交的情况下调用Session.close()
时,会出现此问题。该更改还具有以下效果:无论会话如何被丢弃,在非自动提交模式下使用Session
对象时,您现在都将在日志中看到显式的“ROLLBACK”。感谢 Jeff Dairiki 和 Laurence Rowe 在此处分离问题。
参考:#2907
sqlite
- [sqlite] [bug]
修复了 SQLite 编译器无法将诸如“literal binds”之类的编译器参数传递到 CAST 表达式中的错误。
mssql
- [mssql] [feature]
为UniqueConstraint
和PrimaryKeyConstraint
构造添加了一个mssql_clustered
选项;在 SQL Server 上,这将在 DDL 中的约束结构中添加CLUSTERED
关键字。感谢 Derek Harland 的 Pullreq。
oracle
- [oracle] [bug]
已经观察到在 Python 2.xx 中使用 cx_Oracle 的“outputtypehandler”来将字符串值强制转换为 Unicode 是非常昂贵的;即使 cx_Oracle 是用 C 写的,当你将 Pythonunicode
原语传递给 cursor.var() 并与输出处理程序关联时,库会将每次转换都记录为 Python 函数调用,带有所有必要的开销;尽管在 Python 3 中运行时,所有字符串也被无条件地转换为 Unicode,但它不会产生这种开销,这意味着 cx_Oracle 在 Py2K 中未能使用高性能技术。由于 SQLAlchemy 不能轻松地按列选择这种类型处理程序的方式,处理程序被无条件地组装,从而为所有字符串访问增加了开销。
因此,这个逻辑已被 SQLAlchemy 自己的 Unicode 转换系统取代,现在只在请求为 Unicode 的列中在 Py2K 中生效。当使用 C 扩展时,SQLAlchemy 的系统似乎比 cx_Oracle 的快 2-3 倍。此外,SQLAlchemy 的 Unicode 转换已经得到增强,以便当需要“条件”转换器(现在需要用于 Oracle 后端)时,在 C 中执行“已经是 Unicode”的检查,不再引入显著的开销。
这个改变对 cx_Oracle 后端有两个影响。一个是在 Py2K 中,如果没有明确请求 Unicode 类型或 convert_unicode=True,那么字符串值现在将返回为str
,而不是unicode
- 这种行为类似于 MySQL 这样的后端。此外,在请求带有 cx_Oracle 后端的 Unicode 值时,如果没有使用 C 扩展,现在每列都会有一个 isinstance() 检查的额外开销。这种权衡是因为它可以被解决,并且不再对大多数非 Unicode 字符串的 Oracle 结果列造成性能负担。
参考:#2911
杂项
- [bug] [pool]
PoolEvents.reset()
事件的参数名称已更改为dbapi_connection
和connection_record
,以保持与所有其他池事件的一致性。预计任何现有监听器对于这个相对新的且很少使用的事件都在任何情况下使用位置样式接收参数。 - [bug] [cextensions] [py3k]
修复了一个问题,即 Py3K 中的 C 扩展正在使用错误的 API 来指定顶层模块函数,这在 Python 3.4b2 中会出错。Py3.4b2 将 PyMODINIT_FUNC 更改为返回“void”而不是PyObject *
,因此我们现在确保使用“PyMODINIT_FUNC”而不是直接使用PyObject *
。感谢 cgohlke 提交的拉取请求。
SqlAlchemy 2.0 中文文档(六十四)(5)https://developer.aliyun.com/article/1560875