SQLAlchemy 2.0 文档
列 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.default
和 Column.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.default
和 Column.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.default
和 Column.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.default
和 Column.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()
集合上 CursorResult
。 CursorResult.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()
方法可以与 Insert
或 Update
结构一起使用,以指示这些值应该被返回。
有关在 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
属性获得。
当 Sequence
与 Column
关联作为其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
对象被视为一个独立的架构结构,它可以独立存在或在表之间共享。
将 Sequence
与 MetaData
显式关联,可以实现以下行为。
在目标
MetaData
中,Sequence
会继承MetaData.schema
参数,这会影响 CREATE / DROP DDL 的生成,以及在 SQL 语句中Sequence.next_value()
函数的渲染方式。MetaData.create_all()
和MetaData.drop_all()
方法会为该Sequence
生成 CREATE / DROP 语句,即使该Sequence
不与任何Table
/Column
关联,这些Table
/Column
是该MetaData
的成员。
将 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
关联起来,这也确保了 Sequence
与 MetaData
集合的参数完全关联起来,包括默认模式(如果有)。
计算列 (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
标志可以指定为 True
或 False
,以指示是否应该在 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
。
另请参阅
标识列 (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 使用自定义语法,只支持
start
和increment
参数,并忽略其他所有参数。
当 Identity
与不受支持的后端一起使用时,它将被忽略,并将使用自动递增列的默认 SQLAlchemy 逻辑。
当 Column
同时指定了 Identity
并且还将 Column.autoincrement
设置为 False
时,将引发错误。
另请参阅
默认对象 API¶
对象名称 | 描述 |
---|---|
列上的普通默认值。 |
|
定义生成列,即“GENERATED ALWAYS AS”语法。 |
|
DDL 指定的 DEFAULT 列值。 |
|
列默认值的基类。 |
|
透明数据库端默认值的标记。 |
|
定义标识列,即“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”语法。 |
|
表示命名的数据库序列。 |
- 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 中的新增功能。
成员
-
method
sqlalchemy.schema.Computed.
__init__(sqltext: _DDLColumnArgument, persisted: bool | None = None) → None¶ 构造一个 GENERATED ALWAYS AS DDL 构造,以伴随
Column
。- 参数:
sqltext¶ –
包含列生成表达式的字符串,该表达式将按原样使用,或者是一个 SQL 表达式构造,例如
text()
对象。如果作为字符串给出,则该对象将被转换为text()
对象。警告
传递给
Computed
的Computed.sqltext
参数可以作为 Python 字符串参数传递,该参数将被视为可信 SQL 文本,并按原样呈现。不要将不可信的输入传递给此参数。persisted¶ –
可选,控制此列应如何由数据库持久化。可能的值是
None
,默认情况下,它将使用数据库定义的默认持久性。True
,将呈现GENERATED ALWAYS AS ... STORED
,或者针对目标数据库的等效项(如果支持)。False
,将呈现GENERATED ALWAYS AS ... VIRTUAL
,或者针对目标数据库的等效项(如果支持)。
当 DDL 发射到目标数据库时,如果数据库不支持该持久性选项,指定
True
或False
可能会引发错误。将此参数保留为其默认值None
对于所有支持GENERATED ALWAYS AS
的数据库来说都是可以保证成功的。
-
method
sqlalchemy.schema.Computed.
copy(*, target_table: Table | None = None, **kw: Any) → Computed¶ 从版本 1.4 开始已弃用: 方法
Computed.copy()
已弃用,将在未来版本中删除。
-
method
- class sqlalchemy.schema.ColumnDefault¶
列上的普通默认值。
这可以对应于一个常量,一个可调用函数或一个 SQL 子句。
只要使用
Column
的default
、onupdate
参数,就会自动生成ColumnDefault
。也可以按位置传递ColumnDefault
。例如,以下
Column('foo', Integer, default=50)
等同于
Column('foo', Integer, ColumnDefault(50))
类签名
class
sqlalchemy.schema.ColumnDefault
(sqlalchemy.schema.DefaultGenerator
,abc.ABC
)
- class sqlalchemy.schema.DefaultClause¶
DDL 指定的 DEFAULT 列值。
DefaultClause
是一个FetchedValue
,它在发出“CREATE TABLE”时还会生成一个“DEFAULT”子句。只要使用
Column
的server_default
、server_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
对象表示数据库序列的名称和配置参数。它还表示可以通过 SQLAlchemyEngine
或Connection
“执行”的构造,为目标数据库呈现适当的“下一个值”函数并返回结果。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¶ – 布尔值,如果为
True
或False
,则显式强制打开或关闭Sequence.name
的引用。如果保留其默认值None
,则基于大小写和保留字的正常引用规则将生效。quote_schema¶ – 设置
schema
名称的引用首选项。metadata¶ –
可选的
MetaData
对象,此Sequence
将与之关联。与MetaData
关联的Sequence
将获得以下功能Sequence
将继承目标MetaData
指定的MetaData.schema
参数,这将影响 CREATE/DROP DDL 的生成(如果有)。Sequence.create()
和Sequence.drop()
方法会自动使用与MetaData
对象绑定的引擎(如果有)。MetaData.create_all()
和MetaData.drop_all()
方法会为该Sequence
生成 CREATE / DROP 语句,即使该Sequence
不与任何Table
/Column
关联,这些Table
/Column
是该MetaData
的成员。
上述行为只有在通过此参数将
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
的适当增量函数。
-
method
- 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 中的新增功能。
成员
类签名
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.start
和Identity.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()
方法已弃用,将在未来版本中删除。
-
method
flambé! 龙和 炼金术士 图片设计由 Rotem Yaari 创建并慷慨捐赠。
使用 Sphinx 7.2.6 创建。最后生成文档:Fri 08 Nov 2024 08:41:19 AM EST