SqlAlchemy 2.0 中文文档(七十三)(5)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS SQL Server,基础系列 2核4GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: SqlAlchemy 2.0 中文文档(七十三)

SqlAlchemy 2.0 中文文档(七十三)(4)https://developer.aliyun.com/article/1562226


核心关键变化

完全删除将字符串 SQL 片段强制转换为 text()

首次在版本 1.0 中添加的警告,描述在将完整 SQL 片段强制转换为 text()时发出的警告,现在已转换为异常。对于像Query.filter()Select.order_by()等方法传递的字符串片段自动转换为text()构造的持续关注,尽管这已发出警告。在Select.order_by()Query.order_by()Select.group_by()Query.group_by()的情况下,字符串标签或列名仍然解析为相应的表达式构造,但如果解析失败,则会引发CompileError,从而防止直接呈现原始 SQL 文本。

#4481 ### “线程本地”引擎策略已弃用

“线程本地引擎策略”是在 SQLAlchemy 0.2 左右添加的,作为解决 SQLAlchemy 0.1  中操作的标准方式的问题的解决方案,可以总结为“线程本地一切”,发现存在不足。回顾起来,似乎相当荒谬,SQLAlchemy  的首次发布在各个方面都是“alpha”,却担心太多用户已经定居在现有 API 上,无法简单地更改它。

SQLAlchemy 的原始用法模型如下:

engine.begin()
table.insert().execute(parameters)
result = table.select().execute()
table.update().execute(parameters)
engine.commit()

在几个月的实际使用后,很明显,假装“连接”或“事务”是一个隐藏的实现细节是一个坏主意,特别是当有人需要同时处理多个数据库连接时。因此,我们今天看到的使用范式被引入,减去了上下文管理器,因为它们在 Python 中尚不存在:

conn = engine.connect()
try:
    trans = conn.begin()
    conn.execute(table.insert(), parameters)
    result = conn.execute(table.select())
    conn.execute(table.update(), parameters)
    trans.commit()
except:
    trans.rollback()
    raise
finally:
    conn.close()

上述范式是人们所需要的,但由于它仍然有点冗长(因为没有上下文管理器),因此保留了旧的工作方式,并成为线程本地引擎策略。

今天,使用 Core 更加简洁,甚至比原始模式更加简洁,这要归功于上下文管理器:

with engine.begin() as conn:
    conn.execute(table.insert(), parameters)
    result = conn.execute(table.select())
    conn.execute(table.update(), parameters)

此时,仍依赖“threadlocal”风格的任何剩余代码将通过此弃用来鼓励现代化 - 该功能应在下一个主要系列的 SQLAlchemy 中完全移除,例如 1.4 版。连接池参数Pool.use_threadlocal也已弃用,因为在大多数情况下实际上没有任何效果,Engine.contextual_connect()方法也是如此,该方法通常与Engine.connect()方法是同义词,除非使用了 threadlocal 引擎。

#4393 ### convert_unicode 参数已弃用

参数String.convert_unicodecreate_engine.convert_unicode已弃用。这些参数的目的是指示  SQLAlchemy 确保在 Python 2 下传递给数据库之前对传入的 Python Unicode  对象进行编码为字节字符串,并期望从数据库返回的字节字符串转换回 Python Unicode 对象。在 Python 3  之前的时代,要做到这一点是一件非常艰巨的事情,因为几乎所有 Python DBAPI 默认情况下都没有启用 Unicode  支持,并且大多数都存在与它们提供的 Unicode 扩展相关的主要问题。最终,SQLAlchemy 添加了 C  扩展,这些扩展的主要目的之一是加快结果集中的 Unicode 解码过程。

一旦引入了 Python 3,DBAPI 开始更全面地支持 Unicode,并且更重要的是,默认情况下支持 Unicode。然而,特定  DBAPI 在何种条件下会或不会从结果返回 Unicode 数据,以及接受 Python Unicode  值作为参数的条件仍然非常复杂。这标志着“convert_unicode”标志开始过时,因为它们不再足以确保仅在需要时进行编码/解码,而不是在不需要时进行。相反,“convert_unicode”开始被  dialects 自动检测。这一部分可以在引擎第一次连接时发出的“SELECT ‘test plain returns’”和“SELECT  ‘test_unicode_returns’”SQL 中看到;方言正在测试当前 DBAPI 及其当前设置和后端数据库连接是否默认返回  Unicode。

结果是,不再需要在任何情况下使用“convert_unicode”标志,如果需要,SQLAlchemy  项目需要知道这些情况及其原因。目前,在所有主要数据库上,使用该标志的 Unicode  往返测试通过了数百次,因此相当有把握地认为它们不再需要,除非是在争议性的非使用情况,例如访问来自传统数据库的错误编码数据,最好使用自定义类型。

#4393 ### 完全移除将字符串 SQL 片段强制转换为 text()

在 1.0 版本中首次添加的警告,描述在将完整 SQL 片段强制转换为 text() 时发出的警告,现已转换为异常。对于将字符串片段传递给诸如Query.filter()Select.order_by()等方法的自动转换成text() 构造的情况仍然存在持续的担忧,尽管已发出警告。对于Select.order_by()Query.order_by()Select.group_by()Query.group_by(),字符串标签或列名仍然解析为相应的表达式构造,但如果解析失败,则引发CompileError,从而防止原始 SQL 文本直接呈现。

#4481

“threadlocal” 引擎策略已弃用

“threadlocal 引擎策略” 是在 SQLAlchemy 0.2 左右添加的,作为 SQLAlchemy 0.1  中标准操作方式的解决方案,这种方式可以总结为“threadlocal everything”,但后来发现存在不足之处。回顾起来,很荒谬的是,即使  SQLAlchemy 的第一个版本在各个方面都是“alpha”版本,仍然担心已有太多用户已经习惯了现有的 API 以至于不能轻易更改。

SQLAlchemy 的原始使用模型如下:

engine.begin()
table.insert().execute(parameters)
result = table.select().execute()
table.update().execute(parameters)
engine.commit()

经过几个月的实际使用,很明显,假装“连接”或“事务”是一个隐藏的实现细节是一个坏主意,特别是当有人需要同时处理多个数据库连接时。因此,我们今天看到的使用范式被引入,减去了上下文管理器,因为它们在 Python 中尚不存在:

conn = engine.connect()
try:
    trans = conn.begin()
    conn.execute(table.insert(), parameters)
    result = conn.execute(table.select())
    conn.execute(table.update(), parameters)
    trans.commit()
except:
    trans.rollback()
    raise
finally:
    conn.close()

上述范式是人们所需要的,但由于仍然有点啰嗦(因为没有上下文管理器),旧的工作方式也被保留下来,并成为线程本地引擎策略。

今天,使用 Core 要简洁得多,甚至比原始模式更简洁,这要归功于上下文管理器:

with engine.begin() as conn:
    conn.execute(table.insert(), parameters)
    result = conn.execute(table.select())
    conn.execute(table.update(), parameters)

此时,任何仍然依赖“threadlocal”风格的代码都将通过此弃用被鼓励进行现代化 - 该功能应在下一个主要的 SQLAlchemy 系列(例如 1.4)中完全移除。连接池参数Pool.use_threadlocal也被弃用,因为在大多数情况下实际上没有任何效果,Engine.contextual_connect()方法也是如此,该方法通常与Engine.connect()方法是同义的,除非使用线程本地引擎。

#4393

convert_unicode 参数已弃用

参数String.convert_unicodecreate_engine.convert_unicode已被弃用。这些参数的目的是指示  SQLAlchemy 在将 Python 2 中的传入 Unicode  对象传递到数据库之前确保对其进行字节串编码,并期望从数据库接收字节串并将其转换回 Python Unicode 对象。在 Python 3  之前的时代,要做到这一点是一个巨大的挑战,因为几乎所有的 Python DBAPI 默认情况下都没有启用 Unicode  支持,并且大多数都存在与其提供的 Unicode 扩展相关的主要问题。最终,SQLAlchemy 添加了 C  扩展,其中这些扩展的主要目的之一是加速结果集中的 Unicode 解码过程。

一旦引入了 Python 3,DBAPI 开始更全面地支持 Unicode,更重要的是,默认情况下支持 Unicode。然而,特定  DBAPI 是否返回 Unicode 数据以及接受 Python Unicode  值作为参数的条件仍然非常复杂。这标志着“convert_unicode”标志开始过时,因为它们不再足以确保仅在需要时进行编码/解码,而不是在不需要时进行。相反,“convert_unicode”开始由方言自动检测。可以从引擎第一次连接时发出的  SQL “SELECT ‘test plain returns’” 和 “SELECT ‘test_unicode_returns’”  中看到其中一部分;方言正在测试当前 DBAPI 与其当前设置和后端数据库连接是否默认返回 Unicode。

最终结果是,在任何情况下,用户对“convert_unicode”标志的使用都不再需要,并且如果需要,SQLAlchemy  项目需要知道这些情况以及原因。当前,在所有主要数据库上,通过了数百个 Unicode  往返测试,而不使用此标志,因此相当有信心不再需要它们,除非在可争议的非使用情况下,例如访问来自遗留数据库的错误编码数据,此时最好使用自定义类型。

#4393

方言改进和更改 - PostgreSQL

为 PostgreSQL 分区表添加了基本的反射支持

SQLAlchemy 可以在 PostgreSQL CREATE TABLE 语句中使用 postgresql_partition_by 标志渲染“PARTITION BY”序列,该标志在版本 1.2.6 中添加。然而,'p' 类型直到现在都不是反射查询的一部分。

给定这样一个模式:

dv = Table(
    "data_values",
    metadata_obj,
    Column("modulus", Integer, nullable=False),
    Column("data", String(30)),
    postgresql_partition_by="range(modulus)",
)
sa.event.listen(
    dv,
    "after_create",
    sa.DDL(
        "CREATE TABLE data_values_4_10 PARTITION OF data_values "
        "FOR VALUES FROM (4) TO (10)"
    ),
)

两个表名 'data_values''data_values_4_10' 将通过 Inspector.get_table_names() 返回,并且列也将通过 Inspector.get_columns('data_values')Inspector.get_columns('data_values_4_10') 返回。这也适用于对这些表使用 Table(..., autoload=True)

#4237 ### 为 PostgreSQL 分区表添加了基本的反射支持

SQLAlchemy 可以在 PostgreSQL CREATE TABLE 语句中使用 postgresql_partition_by 标志渲染“PARTITION BY”序列,该标志在版本 1.2.6 中添加。然而,'p' 类型直到现在都不是反射查询的一部分。

给定这样一个模式:

dv = Table(
    "data_values",
    metadata_obj,
    Column("modulus", Integer, nullable=False),
    Column("data", String(30)),
    postgresql_partition_by="range(modulus)",
)
sa.event.listen(
    dv,
    "after_create",
    sa.DDL(
        "CREATE TABLE data_values_4_10 PARTITION OF data_values "
        "FOR VALUES FROM (4) TO (10)"
    ),
)

两个表名'data_values''data_values_4_10'将从Inspector.get_table_names()返回,并且还将从Inspector.get_columns('data_values')以及Inspector.get_columns('data_values_4_10')返回列。这也适用于使用这些表的Table(..., autoload=True)

#4237

方言改进和变化 - MySQL

协议级别的 ping 现在用于预先 ping

包括 mysqlclient、python-mysql、PyMySQL 和 mysql-connector-python 在内的 MySQL 方言现在使用connection.ping()方法进行池预 ping 功能,详细信息请参见断开处理 - 悲观。这比以前在连接上发出“SELECT 1”的方法要轻量得多。 ### 控制 ON DUPLICATE KEY UPDATE 中参数顺序

ON DUPLICATE KEY UPDATE子句中 UPDATE 参数的顺序现在可以通过传递一个 2 元组列表来明确排序:

from sqlalchemy.dialects.mysql import insert
insert_stmt = insert(my_table).values(id="some_existing_id", data="inserted value")
on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
    [
        ("data", "some data"),
        ("updated_at", func.current_timestamp()),
    ],
)

参见

INSERT…ON DUPLICATE KEY UPDATE (Upsert) ### 协议级别的 ping 现在用于预先 ping

包括 mysqlclient、python-mysql、PyMySQL 和 mysql-connector-python 在内的 MySQL 方言现在使用connection.ping()方法进行池预 ping 功能,详细信息请参见断开处理 - 悲观。这比以前在连接上发出“SELECT 1”的方法要轻量得多。

控制 ON DUPLICATE KEY UPDATE 中参数顺序

ON DUPLICATE KEY UPDATE子句中 UPDATE 参数的顺序现在可以通过传递一个 2 元组列表来明确排序:

from sqlalchemy.dialects.mysql import insert
insert_stmt = insert(my_table).values(id="some_existing_id", data="inserted value")
on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
    [
        ("data", "some data"),
        ("updated_at", func.current_timestamp()),
    ],
)

参见

INSERT…ON DUPLICATE KEY UPDATE (Upsert)

方言改进和变化 - SQLite

对 SQLite JSON 的支持已添加

添加了一个新的数据类型JSON,它代表了JSON基础数据类型的 SQLite 的 json 成员访问函数。实现使用 SQLite 的JSON_EXTRACTJSON_QUOTE函数来提供基本的 JSON 支持。

请注意,数据库中呈现的数据类型本身的名称是“JSON”。这将创建一个带有“numeric”亲和力的 SQLite 数据类型,通常情况下不应该成为问题,除非是由单个整数值组成的 JSON 值的情况。尽管如此,根据 SQLite 自己文档中的示例www.sqlite.org/json1.html,名称 JSON 正在被用于其熟悉性。

#3850 ### 增加对 SQLite 约束中 ON CONFLICT 的支持

SQLite 支持一个非标准的 ON CONFLICT 子句,可以为独立约束以及一些列内约束(如 NOT NULL)指定。通过向诸如UniqueConstraint之类的对象添加sqlite_on_conflict关键字以及几个Column -特定的变体:

some_table = Table(
    "some_table",
    metadata_obj,
    Column("id", Integer, primary_key=True, sqlite_on_conflict_primary_key="FAIL"),
    Column("data", Integer),
    UniqueConstraint("id", "data", sqlite_on_conflict="IGNORE"),
)

上述表在 CREATE TABLE 语句中呈现为:

CREATE  TABLE  some_table  (
  id  INTEGER  NOT  NULL,
  data  INTEGER,
  PRIMARY  KEY  (id)  ON  CONFLICT  FAIL,
  UNIQUE  (id,  data)  ON  CONFLICT  IGNORE
)

另请参阅

ON CONFLICT 支持约束

#4360 ### 增加对 SQLite JSON 的支持

添加了一个新的数据类型JSON,该数据类型代表JSON基本数据类型的 SQLite 的 json 成员访问函数。该实现使用 SQLite 的JSON_EXTRACTJSON_QUOTE函数来提供基本的 JSON 支持。

注意,数据库中呈现的数据类型本身的名称是“JSON”。这将创建一个带有“数字”亲和力的 SQLite 数据类型,这通常不应该是问题,除非 JSON 值仅包含单个整数值。尽管如此,根据 SQLite 自己文档中的示例,www.sqlite.org/json1.html中使用了 JSON 这个名字以保持熟悉性。

#3850

增加对 SQLite 约束中 ON CONFLICT 的支持

SQLite 支持一个非标准的 ON CONFLICT 子句,可以为独立约束以及一些列内约束(如 NOT NULL)指定。通过向诸如UniqueConstraint之类的对象添加sqlite_on_conflict关键字以及几个Column -特定的变体,已为这些子句添加了支持:

some_table = Table(
    "some_table",
    metadata_obj,
    Column("id", Integer, primary_key=True, sqlite_on_conflict_primary_key="FAIL"),
    Column("data", Integer),
    UniqueConstraint("id", "data", sqlite_on_conflict="IGNORE"),
)

上述表在 CREATE TABLE 语句中呈现为:

CREATE  TABLE  some_table  (
  id  INTEGER  NOT  NULL,
  data  INTEGER,
  PRIMARY  KEY  (id)  ON  CONFLICT  FAIL,
  UNIQUE  (id,  data)  ON  CONFLICT  IGNORE
)

另请参阅

ON CONFLICT 支持约束

#4360

方言改进和更改 - Oracle

对于通用 unicode,国家字符数据类型被减弱,可通过选项重新启用

现在,默认情况下,UnicodeUnicodeText 数据类型现在对应于 Oracle 上的 VARCHAR2CLOB 数据类型,而不是 NVARCHAR2NCLOB(也称为“国家”字符集类型)。这将在诸如它们在CREATE TABLE语句中的呈现方式等行为中看到,以及当使用UnicodeUnicodeText绑定参数时,不会传递任何类型对象给setinputsizes();cx_Oracle 会原生处理字符串值。这种变化基于 cx_Oracle 的维护者的建议,即 Oracle 中的“国家”数据类型在很大程度上已经过时且性能不佳。它们还会在某些情况下干扰,比如应用于像trunc()这样的函数的格式说明符时。

当数据库不使用符合 Unicode 标准的字符集时,可能需要使用NVARCHAR2和相关类型的情况。在这种情况下,可以将标志use_nchar_for_unicode传递给create_engine()以重新启用旧行为。

如往常一样,明确使用NVARCHAR2NCLOB数据类型将继续使用NVARCHAR2NCLOB,包��在 DDL 中以及处理带有 cx_Oracle 的setinputsizes()的绑定参数时。

在读取方面,在 Python 2 下已经添加了对 CHAR/VARCHAR/CLOB 结果行的自动 Unicode 转换,以匹配  Python 3 下 cx_Oracle 的行为。为了减轻 cx_Oracle 方言在 Python 2  下先前具有的性能损失,SQLAlchemy 在 Python 2 下使用非常高效(当构建 C 扩展时)的本地 Unicode  处理程序。可以通过将coerce_to_unicode标志设置为 False 来禁用自动 Unicode 强制转换。此标志现在默认为 True,并适用于所有在结果集中返回的字符串数据,这些数据不明确位于Unicode或 Oracle 的 NVARCHAR2/NCHAR/NCLOB 数据类型下。

#4242 ### cx_Oracle 连接参数现代化,废弃的参数已移除

对于 cx_oracle 方言接受的参数以及 URL 字符串进行了一系列现代化处理:

  • 废弃的参数auto_setinputsizesallow_twophaseexclude_setinputsizes已被移除。
  • threaded 参数的值,对于 SQLAlchemy 方言一直默认为 True,现在不再默认生成。SQLAlchemy 的 Connection 对象本身不被视为线程安全,因此不需要传递此标志。
  • threaded 传递给 create_engine() 本身已被弃用。要将 threaded 的值设置为 True,请将其传递给 create_engine.connect_args 字典或使用查询字符串,例如 oracle+cx_oracle://...?threaded=true
  • 现在,传递到 URL 查询字符串的所有参数,如果不被特别消耗,都会传递给 cx_Oracle.connect() 函数。其中一些也会被强制转换为 cx_Oracle 常量或布尔值,包括 modepurityeventsthreaded
  • 与之前一样,所有 cx_Oracle .connect() 参数都通过 create_engine.connect_args 字典接受,文档在这方面是不准确的。

#4369 ### 国家字符数据类型被弱化以支持通用 Unicode,可通过选项重新启用。

默认情况下,UnicodeUnicodeText 数据类型现在对应于 Oracle 上的 VARCHAR2CLOB 数据类型,而不是 NVARCHAR2NCLOB(也称为“国家”字符集类型)。这将在诸如它们在 CREATE TABLE 语句中的呈现方式等行为中看到,以及当使用 UnicodeUnicodeText 绑定参数时,不会传递任何类型对象给 setinputsizes();cx_Oracle 会原生处理字符串值。这一变化基于 cx_Oracle 的维护者的建议,即 Oracle 中的“国家”数据类型在很大程度上已经过时且性能不佳。它们还会在某些情况下干扰,比如应用于 trunc() 等函数的格式说明符时。

可能需要使用 NVARCHAR2 和相关类型的情况是数据库未使用符合 Unicode 标准的字符集。在这种情况下,可以通过将标志 use_nchar_for_unicode 传递给 create_engine() 来重新启用旧行为。

始终如此,在 DDL 中明确使用NVARCHAR2NCLOB数据类型将继续使用NVARCHAR2NCLOB,包括在处理绑定参数时使用 cx_Oracle 的setinputsizes()

在读取方面,在 Python 2 下已添加了 CHAR/VARCHAR/CLOB 结果行的自动 Unicode 转换,以匹配 Python  3 下 cx_Oracle 的行为。为了减轻以前在 Python 2 下 cx_Oracle 方言在这种行为下的性能损失,SQLAlchemy  在 Python 2 下使用了非常高效(当构建了 C 扩展时)的本地 Unicode 处理程序。自动 Unicode 强制转换可以通过将coerce_to_unicode标志设置为 False 来禁用。该标志现在默认为 True,并适用于结果集中返回的所有不明确为Unicode或 Oracle 的 NVARCHAR2/NCHAR/NCLOB 数据类型的字符串数据。

#4242

cx_Oracle 连接参数现代化,弃用的参数已移除

对 cx_oracle 方言接受的参数以及 URL 字符串进行了一系列现代化改进:

  • 弃用的参数auto_setinputsizesallow_twophaseexclude_setinputsizes已被移除。
  • threaded参数的值,对于 SQLAlchemy 方言始终默认为 True,现在不再默认生成。SQLAlchemy 的Connection对象本身不被认为是线程安全的,因此不需要传递此标志。
  • threaded传递给create_engine()本身已被弃用。要将threaded的值设置为True,请将其传递给create_engine.connect_args字典或使用查询字符串,例如oracle+cx_oracle://...?threaded=true
  • 现在,URL 查询字符串中传递的所有参数,如果不被特殊消耗,都会传递给 cx_Oracle.connect()函数。其中一些参数也会被强制转换为 cx_Oracle 常量或布尔值,包括modepurityeventsthreaded
  • 与之前一样,所有 cx_Oracle 的.connect()参数都可以通过create_engine.connect_args字典接受,文档在这方面描述不准确。

#4369

方言改进和变化 - SQL Server

支持 pyodbc fast_executemany

Pyodbc 最近添加的“fast_executemany”模式,在使用 Microsoft ODBC 驱动程序时可用,现在是 pyodbc / mssql 方言的选项。通过create_engine()传递:

engine = create_engine(
    "mssql+pyodbc://scott:tiger@mssql2017:1433/test?driver=ODBC+Driver+13+for+SQL+Server",
    fast_executemany=True,
)

另请参阅

快速执行多模式

#4158 ### 新参数影响 IDENTITY 的起始和增量,使用 Sequence 已被弃用

从 SQL Server 2012 开始,SQL Server 现在支持具有真实CREATE SEQUENCE语法的序列。在#4235中,SQLAlchemy 将添加对这些的支持,使用Sequence方式与任何其他方言相同。然而,当前情况是,Sequence已经在 SQL Server 上重新用途,以影响主键列上IDENTITY规范的“start”和“increment”参数。为了使过渡向正常序列也可用,使用Sequence将在整个 1.3 系列中发出弃用警告。为了影响“start”和“increment”,在Column上使用新的mssql_identity_startmssql_identity_increment参数:

test = Table(
    "test",
    metadata_obj,
    Column(
        "id",
        Integer,
        primary_key=True,
        mssql_identity_start=100,
        mssql_identity_increment=10,
    ),
    Column("name", String(20)),
)

为了在非主键列上发出IDENTITY,这是一个很少使用但有效的 SQL Server 用例,使用Column.autoincrement标志,将其设置为True在目标列上,False在任何整数主键列上:

test = Table(
    "test",
    metadata_obj,
    Column("id", Integer, primary_key=True, autoincrement=False),
    Column("number", Integer, autoincrement=True),
)

另请参阅

自增行为 / IDENTITY 列

#4362

#4235 ### 支持 pyodbc fast_executemany

Pyodbc 最近添加的“fast_executemany”模式,在使用 Microsoft ODBC 驱动程序时可用,现在是 pyodbc / mssql 方言的选项。通过create_engine()传递:

engine = create_engine(
    "mssql+pyodbc://scott:tiger@mssql2017:1433/test?driver=ODBC+Driver+13+for+SQL+Server",
    fast_executemany=True,
)

另请参阅

快速执行多模式

#4158

新参数影响 IDENTITY 的起始和增量,使用 Sequence 已被弃用

从 SQL Server 2012 开始,SQL Server 现在支持具有真实CREATE SEQUENCE语法的序列。在#4235中,SQLAlchemy 将使用Sequence来支持这些,方式与任何其他方言相同。然而,当前情况是,Sequence已经在 SQL Server 上重新用途,以影响主键列上IDENTITY规范的“start”和“increment”参数。为了使过渡向正常序列也可用,使用Sequence将在整个 1.3 系列中发出弃用警告。为了影响“start”和“increment”,请在Column上使用新的mssql_identity_startmssql_identity_increment参数:

test = Table(
    "test",
    metadata_obj,
    Column(
        "id",
        Integer,
        primary_key=True,
        mssql_identity_start=100,
        mssql_identity_increment=10,
    ),
    Column("name", String(20)),
)

为了在非主键列上发出IDENTITY,这是一个很少使用但有效的 SQL Server 用例,可以使用Column.autoincrement标志,在目标列上将其设置为True,在任何整数主键列上将其设置为False

test = Table(
    "test",
    metadata_obj,
    Column("id", Integer, primary_key=True, autoincrement=False),
    Column("number", Integer, autoincrement=True),
)

另请参阅

自动增量行为 / IDENTITY 列

#4362

#4235

更改了 StatementError 的格式(换行和%s)

StatementError的字符串表示引入了两个更改。字符串表示的“detail”和“SQL”部分现在由换行符分隔,并保留了原始 SQL 语句中存在的换行符。目标是提高可读性,同时仍然保持原始错误消息在一行上以便于日志记录。

这意味着以前看起来像这样的错误消息:

sqlalchemy.exc.StatementError: (sqlalchemy.exc.InvalidRequestError) A value is
required for bind parameter 'id' [SQL: 'select * from reviews\nwhere id = ?']
(Background on this error at: https://sqlalche.me/e/cd3x)

现在看起来像这样:

sqlalchemy.exc.StatementError: (sqlalchemy.exc.InvalidRequestError) A value is required for bind parameter 'id'
[SQL: select * from reviews
where id = ?]
(Background on this error at: https://sqlalche.me/e/cd3x)

此更改的主要影响是消费者不能再假设完整的异常消息在单行上,但是从 DBAPI 驱动程序或 SQLAlchemy 内部生成的原始“error”部分仍将在第一行上。

#4500

相关文章
|
4月前
|
SQL 关系型数据库 MySQL
SqlAlchemy 2.0 中文文档(七十四)(5)
SqlAlchemy 2.0 中文文档(七十四)
46 6
|
4月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(七十四)(3)
SqlAlchemy 2.0 中文文档(七十四)
46 1
|
4月前
|
存储 Java 测试技术
SqlAlchemy 2.0 中文文档(七十三)(3)
SqlAlchemy 2.0 中文文档(七十三)
34 8
|
4月前
|
SQL 关系型数据库 测试技术
SqlAlchemy 2.0 中文文档(七十三)(2)
SqlAlchemy 2.0 中文文档(七十三)
44 4
|
4月前
|
SQL Python
SqlAlchemy 2.0 中文文档(七十四)(4)
SqlAlchemy 2.0 中文文档(七十四)
30 6
|
4月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(七十三)(4)
SqlAlchemy 2.0 中文文档(七十三)
36 2
|
4月前
|
SQL 关系型数据库 测试技术
SqlAlchemy 2.0 中文文档(七十三)(1)
SqlAlchemy 2.0 中文文档(七十三)
42 1
|
4月前
|
SQL 关系型数据库 MySQL
SqlAlchemy 2.0 中文文档(七十四)(1)
SqlAlchemy 2.0 中文文档(七十四)
64 1
|
4月前
|
SQL 缓存 关系型数据库
SqlAlchemy 2.0 中文文档(七十四)(2)
SqlAlchemy 2.0 中文文档(七十四)
34 1
|
4月前
|
SQL 关系型数据库 MySQL
SqlAlchemy 2.0 中文文档(三十六)(2)
SqlAlchemy 2.0 中文文档(三十六)
22 0