列 INSERT/UPDATE 默认值

列 INSERT 和 UPDATE 默认值指的是在对行进行 INSERT 或 UPDATE 操作时,在没有为该列提供 INSERT 或 UPDATE 语句中的值的情况下,用于为特定列生成默认值的函数。也就是说,如果一个表有一个名为“timestamp”的列,并且执行了一个不包含该列值的 INSERT 语句,那么 INSERT 默认值将创建一个新的值,例如当前时间,该值将用作要 INSERT 到“timestamp”列中的值。如果语句确实包含该列的值,则默认值不会生效。

列默认值可以是服务器端函数或常量值,这些函数或常量值在DDL中与模式一起定义,也可以是直接在 SQLAlchemy 发出的 INSERT 或 UPDATE 语句中呈现的 SQL 表达式;它们也可以是客户端 Python 函数或常量值,这些函数或常量值在 SQLAlchemy 将数据传递到数据库之前被调用。

注意

列默认值处理程序不应与拦截和修改传入的 INSERT 和 UPDATE 语句值的构造混淆,这些语句值确实作为语句被调用时提供。这被称为数据编组,其中列值在被发送到数据库之前以某种方式被应用程序修改。SQLAlchemy 提供了几种方法来实现这一点,包括使用自定义数据类型SQL 执行事件 以及在 ORM 中的自定义验证器 以及属性事件。列默认值仅在 SQL DML 语句中没有列值时才会被调用。

SQLAlchemy 提供了一系列关于在 INSERT 和 UPDATE 语句期间对缺失值执行的默认值生成函数的功能。选项包括

  • 在 INSERT 和 UPDATE 操作期间用作默认值的标量值

  • 在 INSERT 和 UPDATE 操作期间执行的 Python 函数

  • 嵌入到 INSERT 语句中的 SQL 表达式(或在某些情况下在执行之前执行)

  • 嵌入到 UPDATE 语句中的 SQL 表达式

  • 在 INSERT 期间使用的服务器端默认值

  • 在 UPDATE 期间使用的服务器端触发器的标记

所有 insert/update 默认值的通用规则是,它们只在没有为特定列传递 execute() 参数时才会生效;否则,将使用给定值。

标量默认值

最简单的默认值类型是作为列默认值使用的标量值

Table("mytable", metadata_obj, Column("somecolumn", Integer, default=12))

在上面,如果未提供其他值,则值“12”将在 INSERT 期间绑定为列值。

标量值也可以与 UPDATE 语句关联,尽管这种情况并不常见(因为 UPDATE 语句通常在寻找动态默认值)

Table("mytable", metadata_obj, Column("somecolumn", Integer, onupdate=25))

Python 执行函数

参数 Column.defaultColumn.onupdate 还接受 Python 函数。如果未提供该列的其他值,则在插入或更新时会调用这些函数,并使用返回的值作为该列的值。下面说明了一个简单的“序列”,它为主键列分配一个递增的计数器

# a function which counts upwards
i = 0


def mydefault():
    global i
    i += 1
    return i


t = Table(
    "mytable",
    metadata_obj,
    Column("id", Integer, primary_key=True, default=mydefault),
)

应该注意的是,对于真正的“递增序列”行为,通常应该使用数据库的内置功能,其中可能包括序列对象或其他自动递增功能。对于主键列,SQLAlchemy 在大多数情况下会自动使用这些功能。有关 Column 的 API 文档,包括 Column.autoincrement 标志,以及本章后面关于Sequence 的部分,提供了有关标准主键生成技术的背景信息。

为了说明 onupdate,我们将 Python datetime 函数 now 分配给 Column.onupdate 属性

import datetime

t = Table(
    "mytable",
    metadata_obj,
    Column("id", Integer, primary_key=True),
    # define 'last_updated' to be populated with datetime.now()
    Column("last_updated", DateTime, onupdate=datetime.datetime.now),
)

当执行 update 语句并且没有为 last_updated 传递值时,将执行 datetime.datetime.now() Python 函数,并且其返回值用作 last_updated 的值。请注意,我们提供了 now 作为函数本身,没有调用它(即后面没有括号) - SQLAlchemy 将在语句执行时执行该函数。

上下文相关默认函数

参数 Column.defaultColumn.onupdate 使用的 Python 函数还可以利用当前语句的上下文来确定值。语句的 上下文 是一个内部 SQLAlchemy 对象,其中包含有关正在执行的语句的所有信息,包括其源表达式、与之关联的参数以及游标。在默认值生成方面,上下文的最典型用例是访问正在插入或更新行上的其他值。要访问上下文,请提供一个接受单个 context 参数的函数

def mydefault(context):
    return context.get_current_parameters()["counter"] + 12


t = Table(
    "mytable",
    metadata_obj,
    Column("counter", Integer),
    Column("counter_plus_twelve", Integer, default=mydefault, onupdate=mydefault),
)

上述默认值生成函数被应用,以便它将对所有 INSERT 和 UPDATE 语句执行,其中没有为 counter_plus_twelve 提供值,并且该值将是执行中 counter 列中存在的值加上数字 12。

对于使用“executemany”样式执行的单个语句,例如使用传递给 Connection.execute() 的多个参数集,用户定义的函数将为每组参数调用一次。对于多值 Insert 结构(例如,通过 Insert.values() 方法设置了多个 VALUES 子句)的用例,用户定义的函数也为每组参数调用一次。

当函数被调用时,特殊方法 DefaultExecutionContext.get_current_parameters() 可从上下文对象(DefaultExecutionContext 的子类)中获得。该方法返回一个字典,其中键是列名,值是 INSERT 或 UPDATE 语句中所有值的集合。在多值 INSERT 结构中,与单个 VALUES 子句对应的参数子集将从完整参数字典中隔离出来,并单独返回。

1.2 版本新增: 新增 DefaultExecutionContext.get_current_parameters() 方法,它通过提供将多个 VALUES 子句组织成单个参数字典的服务,改进了仍然存在的 DefaultExecutionContext.current_parameters 属性。

客户端调用的 SQL 表达式

Column.defaultColumn.onupdate 关键字也可以传递 SQL 表达式,在大多数情况下,这些表达式会在 INSERT 或 UPDATE 语句中内联呈现。

t = Table(
    "mytable",
    metadata_obj,
    Column("id", Integer, primary_key=True),
    # define 'create_date' to default to now()
    Column("create_date", DateTime, default=func.now()),
    # define 'key' to pull its default from the 'keyvalues' table
    Column(
        "key",
        String(20),
        default=select(keyvalues.c.key).where(keyvalues.c.type="type1"),
    ),
    # define 'last_modified' to use the current_timestamp SQL function on update
    Column("last_modified", DateTime, onupdate=func.utc_timestamp()),
)

在上面,create_date 列将在 INSERT 语句期间使用 now() SQL 函数的结果填充(根据后端,在大多数情况下编译成 NOW()CURRENT_TIMESTAMP),key 列将使用来自另一个表的 SELECT 子查询的结果填充。当为该表发出 UPDATE 语句时,last_modified 列将使用 SQL UTC_TIMESTAMP() MySQL 函数的值填充。

注意

使用 func 结构使用 SQL 函数时,我们“调用”命名函数,例如用括号,如 func.now()。这与将 Python 可调用函数指定为默认值(如 datetime.datetime)不同,在这种情况下,我们传递函数本身,但我们自己不调用它。在 SQL 函数的情况下,调用 func.now() 会返回 SQL 表达式对象,该对象将“NOW”函数渲染到正在发出的 SQL 中。

Column.defaultColumn.onupdate 指定的默认和更新 SQL 表达式由 SQLAlchemy 在发生 INSERT 或 UPDATE 语句时显式调用,通常在 DML 语句中内联呈现,但在下面列出的某些情况下除外。这与“服务器端”默认值不同,服务器端默认值是表 DDL 定义的一部分,例如“CREATE TABLE”语句的一部分,这可能是更常见的。有关服务器端默认值,请参见下一节 服务器调用的 DDL 显式默认表达式

当使用主键列使用 Column.default 指示的 SQL 表达式时,在某些情况下,SQLAlchemy 必须“预执行”默认生成 SQL 函数,这意味着它在单独的 SELECT 语句中调用,并将生成的值作为参数传递给 INSERT。这仅发生在 INSERT 语句的请求为返回此主键值的主键列上,其中 RETURNING 或 cursor.lastrowid 可能无法使用。一个指定了 Insert 结构的 insert.inline 标志将始终在内联中渲染默认表达式。

当语句使用一组参数执行(即它不是“executemany”样式的执行)时,返回的 CursorResult 将包含一个通过 CursorResult.postfetch_cols() 可访问的集合,其中包含所有 Column 对象的列表,这些对象具有内联执行的默认值。同样,所有绑定到语句的参数,包括所有预执行的 Python 和 SQL 表达式,都存在于 CursorResult.last_inserted_params()CursorResult.last_updated_params() 集合上 CursorResultCursorResult.inserted_primary_key 集合包含插入行的主键值列表(列表,以便单列和复合列主键以相同的格式表示)。

服务器调用的 DDL 显式默认表达式

SQL 表达式默认值的变体是 Column.server_default,它将在 Table.create() 操作期间放置在 CREATE TABLE 语句中。

t = Table(
    "test",
    metadata_obj,
    Column("abc", String(20), server_default="abc"),
    Column("created_at", DateTime, server_default=func.sysdate()),
    Column("index_value", Integer, server_default=text("0")),
)

上面表的创建调用将生成

CREATE TABLE test (
    abc varchar(20) default 'abc',
    created_at datetime default sysdate,
    index_value integer default 0
)

上面的例子说明了 Column.server_default 的两个典型用例,一个是 SQL 函数(上面的例子中的 SYSDATE),另一个是服务器端的常量值(上面的例子中的整数“0”)。建议对任何文字 SQL 值使用 text() 结构,而不是传递原始值,因为 SQLAlchemy 通常不会对这些值执行任何引用或转义。

与客户端生成的表达式一样, Column.server_default 通常可以容纳 SQL 表达式,但是预期这些表达式通常是简单的函数和表达式,而不是更复杂的情况,例如嵌入式 SELECT。

标记隐式生成的值、时间戳和触发列

根据其他服务器端数据库机制在 INSERT 或 UPDATE 时生成新值的列,例如一些平台上看到的 TIMESTAMP 列的数据库特定自动生成行为,以及在 INSERT 或 UPDATE 时调用以生成新值的自定义触发器,可以使用 FetchedValue 作为标记来调用。

from sqlalchemy.schema import FetchedValue

t = Table(
    "test",
    metadata_obj,
    Column("id", Integer, primary_key=True),
    Column("abc", TIMESTAMP, server_default=FetchedValue()),
    Column("def", String(20), server_onupdate=FetchedValue()),
)

FetchedValue 指示器不会影响 CREATE TABLE 呈现的 DDL。相反,它将该列标记为一个在 INSERT 或 UPDATE 语句期间将由数据库填充新值的列,并且对于支持的数据库,可以用于指示该列应该作为语句的 RETURNING 或 OUTPUT 子句的一部分。SQLAlchemy ORM 等工具然后利用此标记,以便知道如何在执行此类操作后获取该列的值。特别是, ValuesBase.return_defaults() 方法可以与 InsertUpdate 结构一起使用,以指示这些值应该被返回。

有关在 ORM 中使用 FetchedValue 的详细信息,请参阅 获取服务器生成的默认值

警告

Column.server_onupdate 指令目前不会生成 MySQL 的“ON UPDATE CURRENT_TIMESTAMP()”子句。有关如何生成此子句的背景信息,请参阅 为 MySQL/MariaDB 的 explicit_defaults_for_timestamp 渲染 ON UPDATE CURRENT TIMESTAMP

定义序列

SQLAlchemy 使用 Sequence 对象来表示数据库序列,它被认为是“列默认值”的特殊情况。它只对明确支持序列的数据库有效,在 SQLAlchemy 包含的方言中,包括 PostgreSQL、Oracle、MS SQL Server 和 MariaDB。 Sequence 对象在其他情况下被忽略。

提示

在较新的数据库引擎中,Identity 结构比 Sequence 更适合生成整型主键值。有关此结构的背景信息,请参阅部分 标识列 (GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY)

Sequence 可以放置在任何列上,作为在 INSERT 操作期间使用的“默认”生成器,也可以根据需要配置为在 UPDATE 操作期间触发。它最常与单个整型主键列结合使用。

table = Table(
    "cartitems",
    metadata_obj,
    Column(
        "cart_id",
        Integer,
        Sequence("cart_id_seq", start=1),
        primary_key=True,
    ),
    Column("description", String(40)),
    Column("createdate", DateTime()),
)

在上面,表 cartitems 与名为 cart_id_seq 的序列相关联。为上述表发出 MetaData.create_all() 将包括

CREATE SEQUENCE cart_id_seq START WITH 1

CREATE TABLE cartitems (
  cart_id INTEGER NOT NULL,
  description VARCHAR(40),
  createdate TIMESTAMP WITHOUT TIME ZONE,
  PRIMARY KEY (cart_id)
)

提示

在使用具有显式模式名称的表(详细说明请参阅 指定模式名称)时,Table 的配置模式不会自动由嵌入式 Sequence 共享,而是指定 Sequence.schema

Sequence("cart_id_seq", start=1, schema="some_schema")

Sequence 也可以自动使用 MetaData.schema 设置在正在使用的 MetaData 上;有关背景信息,请参阅 将序列与元数据关联

Insert DML 结构对 cartitems 表进行调用时,如果没有为 cart_id 列传递显式值,cart_id_seq 序列将用于在参与的后台生成值。通常,序列函数嵌入在 INSERT 语句中,该语句与 RETURNING 结合使用,以便将新生成的值返回到 Python 进程。

INSERT INTO cartitems (cart_id, description, createdate)
VALUES (next_val(cart_id_seq), 'some description', '2015-10-15 12:00:15')
RETURNING cart_id

当使用 Connection.execute() 调用 Insert 结构时,新生成的主键标识符(包括但不限于使用 Sequence 生成的标识符)可从 CursorResult 结构中使用 CursorResult.inserted_primary_key 属性获得。

SequenceColumn 关联作为其Python 端默认生成器时,Sequence 也将受到“CREATE SEQUENCE”和“DROP SEQUENCE”DDL 的影响,当对拥有者 Table 发出类似的 DDL 时,例如当使用 MetaData.create_all() 为一系列表生成 DDL 时。

Sequence 也可以直接与 MetaData 结构关联。这允许 Sequence 同时在多个 Table 中使用,并且还允许继承 MetaData.schema 参数。有关背景信息,请参阅部分 将序列与元数据关联

在 SERIAL 列上关联序列

PostgreSQL 的 SERIAL 数据类型是一种自动递增类型,这意味着在发出 CREATE TABLE 时隐式创建 PostgreSQL 序列。当为 Column 指示时,Sequence 结构可以通过为 Sequence.optional 参数指定 True 的值来表明它不应该在这种特定情况下使用。这允许给定的 Sequence 用于没有其他主键生成系统的后端,但忽略诸如 PostgreSQL 之类的后端,这些后端将自动为特定列生成序列。

table = Table(
    "cartitems",
    metadata_obj,
    Column(
        "cart_id",
        Integer,
        # use an explicit Sequence where available, but not on
        # PostgreSQL where SERIAL will be used
        Sequence("cart_id_seq", start=1, optional=True),
        primary_key=True,
    ),
    Column("description", String(40)),
    Column("createdate", DateTime()),
)

在上面的示例中,PostgreSQL 的 CREATE TABLE 将对 cart_id 列使用 SERIAL 数据类型,并且 cart_id_seq 序列将被忽略。但是,在 Oracle 上,cart_id_seq 序列将被显式创建。

提示

这种特定于 SERIAL 和 SEQUENCE 的交互方式相当古老,就像在其他情况下一样,使用 Identity 而不是它将简化操作,只需在所有支持的后端上使用 IDENTITY 即可。

单独执行序列

SEQUENCE 是 SQL 中的一级架构对象,可用于在数据库中独立生成值。如果您有一个 Sequence 对象,可以通过将它直接传递给 SQL 执行方法来使用其“下一个值”指令。

with my_engine.connect() as conn:
    seq = Sequence("some_sequence", start=1)
    nextid = conn.execute(seq)

为了将 Sequence 的“下一个值”函数嵌入到 SQL 语句(如 SELECT 或 INSERT)中,请使用 Sequence.next_value() 方法,该方法将在语句编译时呈现适合目标后端的 SQL 函数。

>>> my_seq = Sequence("some_sequence", start=1)
>>> stmt = select(my_seq.next_value())
>>> print(stmt.compile(dialect=postgresql.dialect()))
SELECT nextval('some_sequence') AS next_value_1

将序列与元数据关联

对于要与任意 Table 对象关联的 Sequence,可以使用 Sequence.metadata 参数将 Sequence 与特定 MetaData 关联。

seq = Sequence("my_general_seq", metadata=metadata_obj, start=1)

然后,此类序列可以以通常的方式与列关联。

table = Table(
    "cartitems",
    metadata_obj,
    seq,
    Column("description", String(40)),
    Column("createdate", DateTime()),
)

在上面的示例中,Sequence 对象被视为一个独立的架构结构,它可以独立存在或在表之间共享。

SequenceMetaData 显式关联,可以实现以下行为。

将 Sequence 作为服务器端默认值关联

注意

以下技术仅适用于 PostgreSQL 数据库,不适用于 Oracle。

前面的部分说明了如何将一个 Sequence 与一个 Column 作为 **Python 侧默认生成器** 关联起来。

Column(
    "cart_id",
    Integer,
    Sequence("cart_id_seq", metadata=metadata_obj, start=1),
    primary_key=True,
)

在上述情况下,当相关 Table 受到 CREATE / DROP 的影响时,Sequence 会自动地接受 CREATE SEQUENCE / DROP SEQUENCE DDL 的处理。但是,当 CREATE TABLE 被发出时,该序列 **不会** 作为该列的服务器端默认值存在。

如果我们希望序列被用作服务器端默认值,这意味着即使从 SQL 命令行向表发出 INSERT 命令,该序列也会生效,我们可以使用 Column.server_default 参数,结合序列的生成函数,该函数可以通过 Sequence.next_value() 方法获取。下面我们展示了同一个 Sequence 被关联到 Column 的情况,它既是 Python 侧的默认生成器,也是服务器端的默认生成器。

cart_id_seq = Sequence("cart_id_seq", metadata=metadata_obj, start=1)
table = Table(
    "cartitems",
    metadata_obj,
    Column(
        "cart_id",
        Integer,
        cart_id_seq,
        server_default=cart_id_seq.next_value(),
        primary_key=True,
    ),
    Column("description", String(40)),
    Column("createdate", DateTime()),
)

或者使用 ORM

class CartItem(Base):
    __tablename__ = "cartitems"

    cart_id_seq = Sequence("cart_id_seq", metadata=Base.metadata, start=1)
    cart_id = Column(
        Integer, cart_id_seq, server_default=cart_id_seq.next_value(), primary_key=True
    )
    description = Column(String(40))
    createdate = Column(DateTime)

当“CREATE TABLE”语句被发出时,在 PostgreSQL 上它会被发出为

CREATE TABLE cartitems (
    cart_id INTEGER DEFAULT nextval('cart_id_seq') NOT NULL,
    description VARCHAR(40),
    createdate TIMESTAMP WITHOUT TIME ZONE,
    PRIMARY KEY (cart_id)
)

Sequence 同时放置在 Python 侧和服务器端的默认生成上下文中,确保“主键获取”逻辑在所有情况下都能正常工作。通常情况下,支持序列的数据库也支持 INSERT 语句的 RETURNING,当 SQLAlchemy 发出此语句时,会自动使用 RETURNING。但是,如果某个特定插入操作不使用 RETURNING,那么 SQLAlchemy 会更倾向于在 INSERT 语句本身之外“预执行”序列,这只有当序列包含在 Python 侧的默认生成器函数中时才会生效。

此示例还将 Sequence 直接与封闭的 MetaData 关联起来,这也确保了 SequenceMetaData 集合的参数完全关联起来,包括默认模式(如果有)。

另请参阅

序列/SERIAL/IDENTITY - 在 PostgreSQL 方言文档中

RETURNING 支持 - 在 Oracle 方言文档中

计算列 (GENERATED ALWAYS AS)

版本 1.3.11 中的新增功能。

Computed 结构允许将 Column 在 DDL 中声明为“GENERATED ALWAYS AS”列,即由数据库服务器计算其值的列。该结构接受一个 SQL 表达式,通常以字符串或 text() 结构的方式以文本形式声明,与 CheckConstraint 类似。然后,数据库服务器会解释该 SQL 表达式,以便为行中的该列确定值。

示例

from sqlalchemy import Table, Column, MetaData, Integer, Computed

metadata_obj = MetaData()

square = Table(
    "square",
    metadata_obj,
    Column("id", Integer, primary_key=True),
    Column("side", Integer),
    Column("area", Integer, Computed("side * side")),
    Column("perimeter", Integer, Computed("4 * side")),
)

在 PostgreSQL 12 后端运行时,square 表的 DDL 将如下所示

CREATE TABLE square (
    id SERIAL NOT NULL,
    side INTEGER,
    area INTEGER GENERATED ALWAYS AS (side * side) STORED,
    perimeter INTEGER GENERATED ALWAYS AS (4 * side) STORED,
    PRIMARY KEY (id)
)

值是在 INSERT 和 UPDATE 时持久化,还是在获取时计算,这是数据库的实现细节;前者被称为“存储”,后者被称为“虚拟”。一些数据库实现同时支持这两种方法,而另一些只支持其中一种。可选的 Computed.persisted 标志可以指定为 TrueFalse,以指示是否应该在 DDL 中渲染“STORED”或“VIRTUAL”关键字,但是,如果目标后端不支持该关键字,则会导致错误;如果未设置该标志,则会使用目标后端的工作默认值。

Computed 结构是 FetchedValue 对象的子类,它会将自己设置为目标 Column 的“服务器默认值”和“服务器更新时”生成器,这意味着它在生成 INSERT 和 UPDATE 语句时会被视为默认生成列,并且在使用 ORM 时会被视为生成列。这包括它将成为数据库的 RETURNING 子句的一部分,对于支持 RETURNING 的数据库,生成的值将被预先获取。

注意

定义了 Computed 结构的 Column 可能无法存储任何超出服务器应用于它的值的值;当将此类列的值传递给 INSERT 或 UPDATE 以写入时,SQLAlchemy 的行为目前是忽略该值。

目前已知以下数据库支持“GENERATED ALWAYS AS”:

  • MySQL 5.7 及更高版本

  • MariaDB 10.x 系列及更高版本

  • PostgreSQL 12 及更高版本

  • Oracle - 不过需要注意的是,RETURNING 与 UPDATE 的配合使用存在问题(当渲染包含计算列的 UPDATE..RETURNING 时,会发出相应的警告)

  • Microsoft SQL Server

  • SQLite 3.31 及更高版本

Computed 与不支持的后端一起使用时,如果目标方言不支持它,则尝试渲染该结构时会引发 CompileError。否则,如果方言支持该结构,但所使用的特定数据库服务器版本不支持,则当将 DDL 发出到数据库时,会引发 DBAPIError 的子类,通常是 OperationalError

另请参阅

Computed

标识列 (GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY)

版本 1.4 中的新增功能。

Identity 结构允许将 Column 声明为标识列,并在 DDL 中渲染为“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”。标识列的值由数据库服务器使用递增(或递减)序列自动生成。该结构与 Sequence 共享大多数控制数据库行为的选项。

示例

from sqlalchemy import Table, Column, MetaData, Integer, Identity, String

metadata_obj = MetaData()

data = Table(
    "data",
    metadata_obj,
    Column("id", Integer, Identity(start=42, cycle=True), primary_key=True),
    Column("data", String),
)

在 PostgreSQL 12 后端运行时,data 表的 DDL 将如下所示

CREATE TABLE data (
    id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 42 CYCLE) NOT NULL,
    data VARCHAR,
    PRIMARY KEY (id)
)

数据库将在插入时为 id 列生成一个值,从 42 开始,前提是语句中没有为 id 列提供值。标识列还可以要求数据库生成列的值,忽略语句传递的值或引发错误,具体取决于后端。若要激活此模式,请在 Identity 构造中将参数 Identity.always 设置为 True。将此参数添加到前面的示例中将生成以下 DDL

CREATE TABLE data (
    id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 42 CYCLE) NOT NULL,
    data VARCHAR,
    PRIMARY KEY (id)
)

Identity 构造是 FetchedValue 对象的子类,并将自身设置为目标 Column 的“服务器默认”生成器,这意味着它将被视为生成列,当生成 INSERT 语句时,以及当使用 ORM 时,它将被提取为生成列。这包括它将是数据库 RETURNING 子句的一部分,对于支持 RETURNING 的数据库,生成的价值观是要急切地提取。

Identity 构造目前已知以下后端支持

  • PostgreSQL 版本 10 及更高版本。

  • Oracle 版本 12 及更高版本。它还支持传递 always=None 以启用默认生成的模式,以及参数 on_null=True 以与“BY DEFAULT”标识列一起指定“ON NULL”。

  • Microsoft SQL Server。MSSQL 使用自定义语法,只支持 startincrement 参数,并忽略其他所有参数。

Identity 与不受支持的后端一起使用时,它将被忽略,并将使用自动递增列的默认 SQLAlchemy 逻辑。

Column 同时指定了 Identity 并且还将 Column.autoincrement 设置为 False 时,将引发错误。

另请参阅

Identity

默认对象 API

对象名称 描述

ColumnDefault

列上的普通默认值。

Computed

定义生成列,即“GENERATED ALWAYS AS”语法。

DefaultClause

DDL 指定的 DEFAULT 列值。

DefaultGenerator

默认值的基类。

FetchedValue

透明数据库端默认值的标记。

Identity

定义标识列,即“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”语法。

Sequence

表示命名的数据库序列。

class sqlalchemy.schema.Computed

定义生成列,即“GENERATED ALWAYS AS”语法。

Computed 构造是在 Column 对象的参数列表中添加的内联构造。

from sqlalchemy import Computed

Table('square', metadata_obj,
    Column('side', Float, nullable=False),
    Column('area', Float, Computed('side * side'))
)

有关完整详细信息,请参阅下面的链接文档。

版本 1.3.11 中的新增功能。

成员

__init__(), copy()

method sqlalchemy.schema.Computed.__init__(sqltext: _DDLColumnArgument, persisted: bool | None = None) None

构造一个 GENERATED ALWAYS AS DDL 构造,以伴随 Column

参数:
  • sqltext

    包含列生成表达式的字符串,该表达式将按原样使用,或者是一个 SQL 表达式构造,例如 text() 对象。如果作为字符串给出,则该对象将被转换为 text() 对象。

    警告

    传递给 ComputedComputed.sqltext 参数可以作为 Python 字符串参数传递,该参数将被视为可信 SQL 文本,并按原样呈现。不要将不可信的输入传递给此参数

  • persisted

    可选,控制此列应如何由数据库持久化。可能的值是

    • None,默认情况下,它将使用数据库定义的默认持久性。

    • True,将呈现 GENERATED ALWAYS AS ... STORED,或者针对目标数据库的等效项(如果支持)。

    • False,将呈现 GENERATED ALWAYS AS ... VIRTUAL,或者针对目标数据库的等效项(如果支持)。

    当 DDL 发射到目标数据库时,如果数据库不支持该持久性选项,指定 TrueFalse 可能会引发错误。将此参数保留为其默认值 None 对于所有支持 GENERATED ALWAYS AS 的数据库来说都是可以保证成功的。

method sqlalchemy.schema.Computed.copy(*, target_table: Table | None = None, **kw: Any) Computed

从版本 1.4 开始已弃用: 方法 Computed.copy() 已弃用,将在未来版本中删除。

class sqlalchemy.schema.ColumnDefault

列上的普通默认值。

这可以对应于一个常量,一个可调用函数或一个 SQL 子句。

只要使用 Columndefaultonupdate 参数,就会自动生成 ColumnDefault。也可以按位置传递 ColumnDefault

例如,以下

Column('foo', Integer, default=50)

等同于

Column('foo', Integer, ColumnDefault(50))
class sqlalchemy.schema.DefaultClause

DDL 指定的 DEFAULT 列值。

DefaultClause 是一个 FetchedValue,它在发出“CREATE TABLE”时还会生成一个“DEFAULT”子句。

只要使用 Columnserver_defaultserver_onupdate 参数,就会自动生成 DefaultClause。也可以按位置传递 DefaultClause

例如,以下

Column('foo', Integer, server_default="50")

等同于

Column('foo', Integer, DefaultClause("50"))
class sqlalchemy.schema.DefaultGenerator

默认值的基类。

此对象仅存在于 column.default 或 column.onupdate 上。它作为服务器默认值无效。

class sqlalchemy.schema.FetchedValue

透明数据库端默认值的标记。

当数据库配置为为列提供一些自动默认值时,使用 FetchedValue

例如

Column('foo', Integer, FetchedValue())

将表明在 INSERT 期间,一些触发器或默认值生成器将为 foo 列创建一个新值。

类签名

class sqlalchemy.schema.FetchedValue (sqlalchemy.sql.expression.SchemaEventTarget)

class sqlalchemy.schema.Sequence

表示命名的数据库序列。

Sequence 对象表示数据库序列的名称和配置参数。它还表示可以通过 SQLAlchemy EngineConnection “执行”的构造,为目标数据库呈现适当的“下一个值”函数并返回结果。

Sequence 通常与主键列相关联

some_table = Table(
    'some_table', metadata,
    Column('id', Integer, Sequence('some_table_seq', start=1),
    primary_key=True)
)

当为上述 Table 发出 CREATE TABLE 时,如果目标平台支持序列,则也会发出 CREATE SEQUENCE 语句。对于不支持序列的平台,Sequence 构造将被忽略。

类签名

class sqlalchemy.schema.Sequence (sqlalchemy.schema.HasSchemaAttr, sqlalchemy.schema.IdentityOptions, sqlalchemy.schema.DefaultGenerator)

method sqlalchemy.schema.Sequence.__init__(name: str, start: int | None = None, increment: int | None = None, minvalue: int | None = None, maxvalue: int | None = None, nominvalue: bool | None = None, nomaxvalue: bool | None = None, cycle: bool | None = None, schema: str | Literal[SchemaConst.BLANK_SCHEMA] | None = None, cache: int | None = None, order: bool | None = None, data_type: _TypeEngineArgument[int] | None = None, optional: bool = False, quote: bool | None = None, metadata: MetaData | None = None, quote_schema: bool | None = None, for_update: bool = False) None

构造一个 Sequence 对象。

参数:
  • name – 序列的名称。

  • start

    序列的起始索引。该值在发出 CREATE SEQUENCE 命令到数据库时用作“START WITH”子句的值。如果为 None,则省略该子句,这在大多数平台上表示起始值为 1。

    Changed in version 2.0: 为了使 DDL 发出“START WITH”,Sequence.start 参数是必需的。这是对版本 1.4 中更改的逆转,如果未包含 Sequence.start,则将隐式渲染“START WITH 1”。有关更多详细信息,请参阅 The Sequence construct reverts to not having any explicit default “start” value; impacts MS SQL Server

  • increment – 序列的增量值。该值在发出 CREATE SEQUENCE 命令到数据库时用作“INCREMENT BY”子句的值。如果为 None,则省略该子句,这在大多数平台上表示增量为 1。

  • minvalue – 序列的最小值。该值在发出 CREATE SEQUENCE 命令到数据库时用作“MINVALUE”子句的值。如果为 None,则省略该子句,这在大多数平台上表示对于升序和降序序列,最小值分别为 1 和 -2^63-1。

  • maxvalue – 序列的最大值。该值在发出 CREATE SEQUENCE 命令到数据库时用作“MAXVALUE”子句的值。如果为 None,则省略该子句,这在大多数平台上表示对于升序和降序序列,最大值分别为 2^63-1 和 -1。

  • nominvalue – 序列没有最小值。该值在发出 CREATE SEQUENCE 命令到数据库时用作“NO MINVALUE”子句的值。如果为 None,则省略该子句,这在大多数平台上表示对于升序和降序序列,最小值分别为 1 和 -2^63-1。

  • nomaxvalue – 序列没有最大值。该值在发出 CREATE SEQUENCE 命令到数据库时用作“NO MAXVALUE”子句的值。如果为 None,则省略该子句,这在大多数平台上表示对于升序和降序序列,最大值分别为 2^63-1 和 -1。

  • cycle – 允许序列在升序或降序序列分别达到 maxvalue 或 minvalue 时环绕。该值在发出 CREATE SEQUENCE 命令到数据库时用作“CYCLE”子句的值。如果达到限制,则生成的下一个数字将分别为 minvalue 或 maxvalue。如果 cycle=False(默认值),则在序列达到其最大值后,对 nextval 的任何调用都会返回错误。

  • schema – 可选的序列模式名称,如果序列位于默认模式之外。当存在 MetaData 时,选择模式名称的规则与 Table.schema 相同。

  • cache – 可选的整数值;序列中预先计算的未来值的个数。渲染 Oracle 和 PostgreSQL 识别的 CACHE 关键字。

  • order – 可选的布尔值;如果为 True,则渲染 Oracle 识别的 ORDER 关键字,表示序列是确定性排序的。可能需要使用 Oracle RAC 提供确定性排序。

  • data_type

    序列返回的类型,适用于允许我们选择 INTEGER、BIGINT 等类型的方言(例如,mssql)。

    1.4.0 版本新增。

  • optional – 布尔值,如果为 True,则表示此 Sequence 对象只需要在没有提供其他生成主键标识符方式的后端上显式生成。目前,它实际上意味着“不要在 PostgreSQL 后端创建此序列,因为 SERIAL 关键字会自动为我们创建一个序列”。

  • quote – 布尔值,如果为 TrueFalse,则显式强制打开或关闭 Sequence.name 的引用。如果保留其默认值 None,则基于大小写和保留字的正常引用规则将生效。

  • quote_schema – 设置 schema 名称的引用首选项。

  • metadata

    可选的 MetaData 对象,此 Sequence 将与之关联。与 MetaData 关联的 Sequence 将获得以下功能

    上述行为只有在通过此参数将 Sequence 显式与 MetaData 关联时才会发生。

    另请参阅

    将序列与元数据关联 - 对 Sequence.metadata 参数的完整讨论。

  • for_update – 表示此 Sequence,在与 Column 关联时,应在该列的表的 UPDATE 语句中调用,而不是在 INSERT 语句中调用,当语句中该列没有其他值时。

method sqlalchemy.schema.Sequence.create(bind: _CreateDropBind, checkfirst: bool = True) None

在数据库中创建此序列。

method sqlalchemy.schema.Sequence.drop(bind: _CreateDropBind, checkfirst: bool = True) None

从数据库中删除此序列。

method sqlalchemy.schema.Sequence.next_value() Function[int]

返回一个 next_value 函数元素,它将在任何 SQL 表达式中渲染此 Sequence 的适当增量函数。

class sqlalchemy.schema.Identity

定义标识列,即“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”语法。

Identity 结构是在 Column 对象的参数列表中添加的内联结构

from sqlalchemy import Identity

Table('foo', metadata_obj,
    Column('id', Integer, Identity())
    Column('description', Text),
)

有关完整详细信息,请参阅下面的链接文档。

版本 1.4 中的新增功能。

成员

__init__(), copy()

类签名

class sqlalchemy.schema.Identity (sqlalchemy.schema.IdentityOptions, sqlalchemy.schema.FetchedValue, sqlalchemy.schema.SchemaItem)

method sqlalchemy.schema.Identity.__init__(always: bool = False, on_null: bool | None = None, start: int | None = None, increment: int | None = None, minvalue: int | None = None, maxvalue: int | None = None, nominvalue: bool | None = None, nomaxvalue: bool | None = None, cycle: bool | None = None, cache: int | None = None, order: bool | None = None) None

构建一个 GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY DDL 结构,以配合 Column

有关大多数参数的完整说明,请参阅 Sequence 文档。

注意

MSSQL 支持此结构作为在列上生成 IDENTITY 的首选替代方案,但它使用非标准语法,仅支持 Identity.startIdentity.increment 。所有其他参数都被忽略。

参数:
  • always – 布尔值,表示标识列的类型。如果指定 False (默认值),则用户指定的值优先。如果指定 True ,则不允许用户指定的值(在某些后端,例如 PostgreSQL,可以指定 OVERRIDING SYSTEM VALUE 或类似的值,以便在 INSERT 中覆盖序列值)。一些后端也为此参数提供默认值, None 可用于省略 DDL 中此部分的呈现。如果后端没有默认值,它将被视为 False

  • on_null – 设置为 True 以与 always=False 标识列一起指定 ON NULL。此选项仅在某些后端(例如 Oracle)上受支持。

  • start – 序列的起始索引。

  • increment – 序列的增量值。

  • minvalue – 序列的最小值。

  • maxvalue – 序列的最大值。

  • nominvalue – 序列没有最小值。

  • nomaxvalue – 序列没有最大值。

  • cycle – 允许序列在达到 maxvalue 或 minvalue 时循环。

  • cache – 可选的整数值;预先计算序列中未来值的数量。

  • order – 可选的布尔值;如果为 true,则呈现 ORDER 关键字。

method sqlalchemy.schema.Identity.copy(**kw: Any) Identity

已弃用自版本 1.4: Identity.copy() 方法已弃用,将在未来版本中删除。