SqlAlchemy-2-0-中文文档-二十-
SqlAlchemy 2.0 中文文档(二十)
插入,更新,删除
INSERT、UPDATE 和 DELETE 语句是基于从 UpdateBase 开始的层次结构构建的。Insert 和 Update 构造基于中介 ValuesBase 构建。
DML 基础构造函数
最顶层的“INSERT”,“UPDATE”,“DELETE”构造函数。
| 对象名称 | 描述 |
|---|---|
| delete(table) | 构造 Delete 对象。 |
| insert(table) | 构造 Insert 对象。 |
| update(table) | 构造一个 Update 对象。 |
function sqlalchemy.sql.expression.delete(table: _DMLTableArgument) → Delete
构造 Delete 对象。
例如:
from sqlalchemy import delete
stmt = (
delete(user_table).
where(user_table.c.id == 5)
)
相似的功能也可以通过 TableClause.delete() 方法在 Table 上使用。
参数:
table – 要从中删除行的表。
参见
使用 UPDATE 和 DELETE 语句 - 在 SQLAlchemy 统一教程 中
function sqlalchemy.sql.expression.insert(table: _DMLTableArgument) → Insert
构造一个 Insert 对象。
例如:
from sqlalchemy import insert
stmt = (
insert(user_table).
values(name='username', fullname='Full Username')
)
相似的功能也可以通过 TableClause.insert() 方法在 Table 上使用。
参见
使用 INSERT 语句 - 在 SQLAlchemy 统一教程 中
参数:
-
table–TableClause插入的主题。 -
values– 要插入的值的集合;参见Insert.values()以获取这里允许的格式描述。可以完全省略;Insert构造也会根据传递给Connection.execute()的参数在执行时动态渲染 VALUES 子句。 -
inline– 如果为 True,则不会尝试检索 SQL 生成的默认值以在语句中提供;特别是,这允许 SQL 表达式在语句中“内联”渲染,而无需事先预先执行它们;对于支持“返回”的后端,这将关闭语句的“隐式返回”功能。
如果同时存在insert.values和编译时绑定参数,则编译时绑定参数将在每个键的基础上覆盖insert.values中指定的信息。
Insert.values中的键可以是Column对象或它们的字符串标识符。每个键可以引用以下之一:
-
一个字面数据值(即字符串,数字等);
-
一个 Column 对象;
-
一个 SELECT 语句。
如果指定了引用此INSERT语句表的SELECT语句,则该语句将与INSERT语句相关联。
另请参阅
使用 INSERT 语句 - 在 SQLAlchemy 统一教程中
function sqlalchemy.sql.expression.update(table: _DMLTableArgument) → Update
构造一个Update对象。
例如:
from sqlalchemy import update
stmt = (
update(user_table).
where(user_table.c.id == 5).
values(name='user #5')
)
通过TableClause.update()方法在Table上也可以实现类似功能。
参数:
table – 代表要更新的数据库表的Table对象。
另请参阅
使用 UPDATE 和 DELETE 语句 - 在 SQLAlchemy 统一教程中
DML 类文档构造函数
DML 基础构造函数的类构造函数文档。
| 对象名称 | 描述 |
|---|---|
| Delete | 代表一个 DELETE 构造。 |
| 插入 | 代表一个插入操作。 |
| 更新 | 代表一个更新操作。 |
| UpdateBase | 形成 INSERT、UPDATE 和 DELETE 语句的基础。 |
| ValuesBase | 为 ValuesBase.values() 提供对 INSERT 和 UPDATE 构造的支持。 |
class sqlalchemy.sql.expression.Delete
代表一个删除操作。
使用 delete() 函数创建 Delete 对象。
成员
where(), returning()
类签名
类 sqlalchemy.sql.expression.Delete (sqlalchemy.sql.expression.DMLWhereBase, sqlalchemy.sql.expression.UpdateBase)
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
继承自 DMLWhereBase.where() 方法的 DMLWhereBase
返回一个新构造,其中给定的表达式已添加到其 WHERE 子句中,如果有的话,通过 AND 连接到现有子句。
Update.where() 和 Delete.where() 都支持多表形式,包括特定于数据库的 UPDATE...FROM 和 DELETE..USING。对于不支持多表的后端,使用多表的跨后端方法是利用相关子查询。查看下面链接的教程部分以获取示例。
另请参见
相关更新
UPDATE..FROM
多表删除
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
继承自 UpdateBase.returning() 方法的 UpdateBase
为该语句添加一个 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
该方法可以多次调用,以将新条目添加到要返回的表达式列表中。
版本 1.4.0b2 中的新功能:该方法可以多次调用,以将新条目添加到要返回的表达式列表中。
给定的列表达式集合应来源于 INSERT、UPDATE 或 DELETE 的目标表。虽然 Column 对象是典型的,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在编译时,RETURNING 子句或数据库等效项将在语句中呈现。对于 INSERT 和 UPDATE,值是新插入/更新的值。对于 DELETE,值是删除的行的值。
在执行时,要返回的列的值通过结果集可用,并可使用CursorResult.fetchone()等进行迭代。对于不原生支持返回值的 DBAPI(即 cx_oracle),SQLAlchemy 将在结果级别上近似此行为,以便提供合理的行为中立性。
请注意,并非所有数据库/DBAPI 支持 RETURNING。对于没有支持的后端,在编译和/或执行时会引发异常。对于支持它的后端,跨后端的功能差异很大,包括对 executemany() 和其他返回多行的语句的限制。请阅读正在使用的数据库的文档注释,以确定 RETURNING 的可用性。
参数:
-
*cols– 一系列列、SQL 表达式或整个表实体要返回。 -
sort_by_parameter_order–对于正在针对多个参数集执行的批量 INSERT,请组织 RETURNING 的结果,使返回的行与传入的参数集的顺序相对应。这仅适用于支持方言的 executemany 执行,并且通常利用 insertmanyvalues 功能。
从版本 2.0.10 开始。
另请参阅
将 RETURNING 行与参数集相关联 - 关于批量 INSERT 的 RETURNING 行排序的背景(核心级别讨论)
将 RETURNING 记录与输入数据顺序相关联 - 与 ORM 批量 INSERT 语句 的使用示例(ORM 级别讨论)
另请参阅
UpdateBase.return_defaults() - 针对单行 INSERT 或 UPDATE,旨在有效地获取服务器端默认值和触发器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程中
class sqlalchemy.sql.expression.Insert
表示一个 INSERT 结构。
Insert 对象是使用 insert() 函数创建的。
成员
values(), returning(), from_select(), inline(), select
类签名
类 sqlalchemy.sql.expression.Insert (sqlalchemy.sql.expression.ValuesBase)
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
继承自 ValuesBase.values() 方法的 ValuesBase
为 INSERT 语句指定固定的 VALUES 子句,或为 UPDATE 指定 SET 子句。
请注意,Insert 和 Update 构造支持根据传递给 Connection.execute() 的参数,在执行时格式化 VALUES 和/或 SET 子句。然而,ValuesBase.values() 方法可以用于将特定一组参数“固定”到语句中。
多次调用 ValuesBase.values() 将产生一个新的构造,每个构造的参数列表都会被修改以包含新传入的参数。在典型情况下,使用单个参数字典,新传入的键将替换前一个构造中的相同键。在基于列表的“多值”构造中,每个新的值列表都会被扩展到现有的值列表上。
参数:
-
**kwargs–键值对表示映射到要渲染到 VALUES 或 SET 子句中的值的
Column的字符串键:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name") -
*args–作为传递键/值参数的替代方案,可以将字典、元组或字典或元组的列表作为单个位置参数传递,以形成语句的 VALUES 或 SET 子句。接受的形式因为是
Insert还是Update构造而��所不同。对于
Insert或Update构造,可以传递一个单独的字典,其工作方式与 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})对于任何形式,但更常见于
Insert构造,也可以接受包含表中每一列的条目的元组:users.insert().values((5, "some name"))Insert构造还支持传递字典或完整表元组的列表,在服务器上会呈现较少见的 SQL 语法“多个值” - 这种语法在后端如 SQLite、PostgreSQL、MySQL 等支持,但不一定适用于其他后端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])上述形式将呈现类似于多个 VALUES 语句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)必须注意,传递多个值并不等同于使用传统的 executemany()形式。上述语法是一种特殊语法,通常不使用。要针对多行发出 INSERT 语句,正常的方法是将多个值列表传递给
Connection.execute()方法,该方法受到所有数据库后端的支持,并且通常对大量参数更有效率。另请参见
发送多个参数 - 介绍了用于 INSERT 和其他语句的多参数集调用的传统 Core 方法。
UPDATE 构造还支持以特定顺序渲染 SET 参数。有关此功能,请参阅
Update.ordered_values()方法。另请参见
Update.ordered_values()
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
继承自 UpdateBase.returning() 方法的 UpdateBase
为此语句添加一个 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
可以多次调用该方法以向返回的表达式列表中添加新条目。
新版本 1.4.0b2 中:可以多次调用该方法以向返回的表达式列表中添加新条目。
给定的列表达式集合应派生自 INSERT、UPDATE 或 DELETE 的目标表。虽然 Column 对象是典型的,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在编译时,将在语句中呈现 RETURNING 子句或数据库等效物。对于 INSERT 和 UPDATE,值是新插入/更新的值。对于 DELETE,值是被删除的行的值。
在执行时,要返回的列的值通过结果集可用,并且可以使用 CursorResult.fetchone() 等进行迭代。对于不原生支持返回值的 DBAPI(即 cx_oracle),SQLAlchemy 将在结果级别近似此行为,以便提供合理数量的行为中立性。
请注意,并非所有数据库/DBAPI 都支持 RETURNING。对于那些没有支持的后端,在编译和/或执行时会引发异常。对于支持它的后端,跨后端的功能差异很大,包括对 executemany() 和其他返回多行语句的限制。请阅读正在使用的数据库的文档注释,以确定 RETURNING 的可用性。
参数:
-
*cols– 要返回的一系列列、SQL 表达式或整个表实体。 -
sort_by_parameter_order–对于针对多个参数集执行的批量插入,组织 RETURNING 的结果,使返回的行与传入的参数集的顺序对应。这仅适用于支持方言的 executemany 执行,并且通常利用了 insertmanyvalues 特性。
新版本 2.0.10 中新增。
另请参阅
将 RETURNING 行与参数集相关联 - 关于批量插入的 RETURNING 行排序的背景(核心级别讨论)
将 RETURNING 记录与输入数据顺序相关联 - 与 ORM 批量插入语句 的使用示例(ORM 级别讨论)
另请参阅
UpdateBase.return_defaults() - 一种针对单行插入或更新的服务器端默认值和触发器的高效获取的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程 中
method from_select(names: Sequence[_DMLColumnArgument], select: Selectable, include_defaults: bool = True) → Self
返回一个新的 Insert 构造,该构造表示一个 INSERT...FROM SELECT 语句。
例如:
sel = select(table1.c.a, table1.c.b).where(table1.c.c > 5)
ins = table2.insert().from_select(['a', 'b'], sel)
参数:
-
names– 字符串列名序列或表示目标列的Column对象。 -
select– 一个select()构造,FromClause或其他可解析为FromClause的构造,比如 ORMQuery对象等。此 FROM 子句返回的列的顺序应与作为names参数发送的列的顺序相对应;虽然在传递给数据库之前不会检查这一点,但如果这些列列表不对应,数据库通常会引发异常。 -
include_defaults–如果为 True,则将在 INSERT 和 SELECT 语句中呈现在
Column对象上指定的非服务器默认值和 SQL 表达式(如 Column INSERT/UPDATE Defaults 中记录的)中未在名称列表中另行指定的值,以便这些值也包含在要插入的数据中。注意
使用 Python 可调用函数的 Python 端默认值仅在整个语句中被调用一次,而不是每行一次。
method inline() → Self
使此 Insert 构造“内联”。
当设置时,不会尝试检索要在语句中提供的 SQL 生成的默认值;特别是,这允许 SQL 表达式在语句中“内联”呈现,而无需事先执行它们;对于支持“returning”的后端,这将关闭语句的“隐式返回”功能。
自版本 1.4 起:Insert.inline 参数现已被 Insert.inline() 方法取代。
attribute select: Select[Any] | None = None
用于 INSERT .. FROM SELECT 的 SELECT 语���
class sqlalchemy.sql.expression.Update
表示一个 Update 构造。
使用 update() 函数创建 Update 对象。
成员
returning(), where(), values(), inline(), ordered_values()
类签名
类 sqlalchemy.sql.expression.Update (sqlalchemy.sql.expression.DMLWhereBase, sqlalchemy.sql.expression.ValuesBase)
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
继承自 UpdateBase.returning() 方法的 UpdateBase
向此语句添加 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
这种方法可以被多次调用,以向要返回的表达式列表中添加新条目。
新版本 1.4.0b2 中添加:这种方法可以被多次调用,以向要返回的表达式列表中添加新条目。
给定的列表达式集合应源自 INSERT、UPDATE 或 DELETE 的目标表。虽然 Column 对象是典型的,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在编译时,RETURNING 子句或数据库等效项将在语句中呈现。对于 INSERT 和 UPDATE,值是新插入/更新的值。对于 DELETE,值是已删除行的值。
在执行时,要返回的列的值通过结果集提供,并且可以使用 CursorResult.fetchone() 等进行迭代。对于原生不支持返回值的 DBAPI(即 cx_oracle 等),SQLAlchemy 将在结果级别近似此行为,以便提供合理数量的行为中性。
请注意,并非所有数据库/DBAPI 都支持 RETURNING。对于那些不支持的后端,编译和/或执行时会引发异常。对于支持的后端,跨后端的功能差异很大,包括对 executemany() 和其他返回多行的语句的限制。请阅读所使用数据库的文档注释,以确定 RETURNING 的可用性。
参数:
-
*cols– 要返回的一系列列、SQL 表达式或整个表实体。 -
sort_by_parameter_order–对于针对多个参数集执行的批量 INSERT,组织 RETURNING 的结果,使返回的行对应于传递的参数集的顺序。这仅适用于支持的方言的 executemany 执行,并通常利用 insertmanyvalues 功能。
新版本 2.0.10 中添加。
另请参阅
将 RETURNING 行与参数集相关联 - 关于批量插入 RETURNING 行排序的背景(核心级讨论)
将 RETURNING 记录与输入数据顺序相关联 - 与 ORM 批量插入语句 一起使用的示例(ORM 级讨论)
另请参阅
UpdateBase.return_defaults() - 针对单行 INSERT 或 UPDATE 的高效提取服务器端默认值和触发器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程中
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
继承自 DMLWhereBase 的 DMLWhereBase.where() 方法
返回一个新的结构,其中包含添加到其 WHERE 子句的给定表达式,并通过 AND 连接到现有子句(如果有)。
Update.where() 和 Delete.where() 都支持多表形式,包括特定于数据库的 UPDATE...FROM 和 DELETE..USING。 对于不支持多表的后端,使用多表的后端不可知方法是利用相关子查询。 有关示例,请参见下面的链接教程部分。
另请参阅
相关更新
UPDATE..FROM
多表删除
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
继承自 ValuesBase 的 ValuesBase.values() 方法
指定 INSERT 语句的固定 VALUES 子句,或者 UPDATE 的 SET 子句。
请注意,Insert 和 Update 结构支持基于传递给 Connection.execute() 的参数对 VALUES 和/或 SET 子句进行每次执行时间格式化。 但是,ValuesBase.values() 方法可用于将特定的一组参数“固定”到语句中。
对 ValuesBase.values() 的多次调用将产生一个新的结构,每个结构的参数列表都被修改以包含发送的新参数。 在单个参数字典的典型情况下,新传递的键将替换上一个结构中的相同键。 在基于列表的“多个值”结构的情况下,每个新值列表都被扩展到现有值列表上。
参数:
-
**kwargs–代表要渲染到 VALUES 或 SET 子句中的值的字符串键的键值对:
users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name") -
*args–作为传递键/值参数的替代方案,可以将字典、元组或字典或元组的列表作为单个位置参数传递,以形成语句的 VALUES 或 SET 子句。所接受的形式因为这是否是一个
Insert或Update构造而异。对于
Insert或Update构造,也可以传递单个字典,其工作方式与 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})也适用于任何形式,但更常见的是对于
Insert构造,也接受包含表中每列的条目的元组:users.insert().values((5, "some name"))Insert构造还支持传递字典或完整表元组的列表,在服务器上,这将呈现较不常见的 SQL 语法“多个值” - 此语法支持后端,例如 SQLite、PostgreSQL、MySQL,但不一定支持其他后端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])上述形式将呈现类似于多个 VALUES 语句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)必须注意传递多个值并不等同于使用传统的 executemany() 形式。上述语法是一个特殊语法,通常不使用。要针对多行发出 INSERT 语句,正常方法是将多个值列表传递给
Connection.execute()方法,此方法受到所有数据库后端的支持,并且对于非常多的参数通常更有效率。另请参阅
发送多个参数 - 介绍传统 Core 方法的多参数集调用方式,用于 INSERT 和其他语句。
UPDATE 构造还支持按特定顺序渲染 SET 参数。有关此功能,请参阅
Update.ordered_values()方法。另请参阅
Update.ordered_values()
method inline() → Self
将此Update 构造“内联”。
当设置时,通过default关键字在Column对象上存在的 SQL 默认值将被‘内联’编译到语句中,而不是预先执行。这意味着它们的值不会在从CursorResult.last_updated_params()返回的字典中可用。
在 1.4 版本中更改:update.inline参数现在被Update.inline()方法取代。
method ordered_values(*args: Tuple[_DMLColumnArgument, Any]) → Self
使用显式参数顺序指定此 UPDATE 语句的 VALUES 子句,该顺序将在生成的 UPDATE 语句的 SET 子句中保持不变。
例如:
stmt = table.update().ordered_values(
("name", "ed"), ("ident", "foo")
)
另请参阅
参数顺序更新 - Update.ordered_values() 方法的完整示例。
在 1.4 版本中更改:Update.ordered_values() 方法取代了update.preserve_parameter_order参数,该参数将在 SQLAlchemy 2.0 中被移除。
class sqlalchemy.sql.expression.UpdateBase
为INSERT、UPDATE和DELETE语句提供基础。
成员
entity\_description, exported\_columns, params(), return\_defaults(), returning(), returning\_column\_descriptions, with\_dialect\_options(), with\_hint()
类签名
类sqlalchemy.sql.expression.UpdateBase (sqlalchemy.sql.roles.DMLRole, sqlalchemy.sql.expression.HasCTE, sqlalchemy.sql.expression.HasCompileState, sqlalchemy.sql.base.DialectKWArgs, sqlalchemy.sql.expression.HasPrefixes, sqlalchemy.sql.expression.Generative, sqlalchemy.sql.expression.ExecutableReturnsRows, sqlalchemy.sql.expression.ClauseElement)
attribute entity_description
返回针对此 DML 构造操作的表和/或实体的启用插件描述。
当使用 ORM 时,此属性通常很有用,因为它返回了一个扩展的结构,其中包含有关映射实体的信息。有关更多背景信息,请参阅 从 ORM 启用的 SELECT 和 DML 语句中检查实体和列。
对于核心语句,此访问器返回的结构派生自 UpdateBase.table 属性,并引用正在插入、更新或删除的Table:
>>> stmt = insert(user_table)
>>> stmt.entity_description
{
"name": "user_table",
"table": Table("user_table", ...)
}
新功能,版本 1.4.33。
另请参阅
UpdateBase.returning_column_descriptions
Select.column_descriptions - select() 构造的实体信息
从 ORM 启用的 SELECT 和 DML 语句中检查实体和列 - ORM 背景
attribute exported_columns
返回该语句的 RETURNING 列作为列集合。
新功能,版本 1.4。
method params(*arg: Any, **kw: Any) → NoReturn
设置语句的参数。
此方法在基类上引发 NotImplementedError,并由ValuesBase覆盖以提供 UPDATE 和 INSERT 的 SET/VALUES 子句。
method return_defaults(*cols: _DMLColumnArgument, supplemental_cols: Iterable[_DMLColumnArgument] | None = None, sort_by_parameter_order: bool = False) → Self
利用 RETURNING 子句以获取服务器端表达式和默认值,仅支持后端。
深度炼金术
UpdateBase.return_defaults()方法被 ORM 用于其内部工作中,用于获取新生成的主键和服务器默认值,特别是为了提供Mapper.eager_defaults ORM 特性的底层实现,以及允许在批量 ORM 插入中支持 RETURNING。其行为相当特殊,实际上不适合一般使用。最终用户应坚持使用UpdateBase.returning()来为他们的 INSERT、UPDATE 和 DELETE 语句添加 RETURNING 子句。
通常,执行单行 INSERT 语句时,会自动填充CursorResult.inserted_primary_key属性,该属性存储了刚刚插入的行的主键,以Row对象的形式,列名作为命名元组键(并且Row._mapping视图也完全填充)。使用的方言选择用于填充这些数据的策略;如果是使用服务器端默认值和/或 SQL 表达式生成的,则通常使用特定于方言的方法(如cursor.lastrowid或RETURNING)来获取新的主键值。
然而,在执行语句之前通过调用UpdateBase.return_defaults()修改语句时,只有支持 RETURNING 并且将Table.implicit_returning参数维持在其默认值True的后端以及维护Table对象的其他行为才会发生。在这些情况下,当从语句的执行返回CursorResult时,不仅CursorResult.inserted_primary_key将像往常一样被填充,CursorResult.returned_defaults属性还将被填充为一个名为Row的命名元组,代表该单行的完整服务器生成值范围,包括任何指定Column.server_default或使用 SQL 表达式的Column.default的列的值。
当使用 insertmanyvalues 调用多行的 INSERT 语句时,UpdateBase.return_defaults()修饰符将会影响CursorResult.inserted_primary_key_rows和CursorResult.returned_defaults_rows属性被完全填充为代表每行新插入的主键值以及新插入的服务器生成值的Row对象列表。CursorResult.inserted_primary_key和CursorResult.returned_defaults属性也将继续被填充为这两个集合的第一行。
如果后端不支持 RETURNING 或者正在使用的 Table 已经禁用了 Table.implicit_returning,那么就不会添加 RETURNING 子句,也不会获取任何额外的数据,但是 INSERT、UPDATE 或 DELETE 语句会正常执行。
例如:
stmt = table.insert().values(data='newdata').return_defaults()
result = connection.execute(stmt)
server_created_at = result.returned_defaults['created_at']
当用于 UPDATE 语句时,UpdateBase.return_defaults() 会查找包含 Column.onupdate 或 Column.server_onupdate 参数的列,当构造默认情况下将包含在 RETURNING 子句中的列时(如果未明确指定列)。当用于 DELETE 语句时,默认情况下不会包含任何列在 RETURNING 中,而是必须明确指定,因为在 DELETE 语句执行时通常不会更改值的列。
从版本 2.0 开始:UpdateBase.return_defaults() 也支持 DELETE 语句,并且已从 ValuesBase 移动到 UpdateBase。
UpdateBase.return_defaults() 方法与 UpdateBase.returning() 方法互斥,在同一条语句上同时使用两者会在 SQL 编译过程中引发错误。因此,INSERT、UPDATE 或 DELETE 语句的 RETURNING 子句一次只能由其中一个方法控制。
UpdateBase.return_defaults() 方法与 UpdateBase.returning() 在以下方面不同:
-
UpdateBase.return_defaults()方法导致CursorResult.returned_defaults集合被填充为 RETURNING 结果的第一行。当使用UpdateBase.returning()时,此属性不会被填充。 -
UpdateBase.return_defaults()与用于获取自动生成的主键值并将其填充到CursorResult.inserted_primary_key属性的现有逻辑兼容。相比之下,使用UpdateBase.returning()将导致CursorResult.inserted_primary_key属性保持未填充状态。 -
UpdateBase.return_defaults()可以针对任何后端调用。不支持 RETURNING 的后端将跳过该功能的使用,而不是引发异常,除非传递了supplemental_cols。对于不支持 RETURNING 或目标Table设置Table.implicit_returning为False的后端,CursorResult.returned_defaults的返回值将为None。 -
使用
executemany()调用的 INSERT 语句在后端数据库驱动程序支持 insertmanyvalues 功能的情况下得到支持,这个功能现在大多数包含在 SQLAlchemy 中的后端都支持。当使用executemany时,CursorResult.returned_defaults_rows和CursorResult.inserted_primary_key_rows访问器将返回插入的默认值和主键。1.4 版本中新增:添加了
CursorResult.returned_defaults_rows和CursorResult.inserted_primary_key_rows访问器。在 2.0 版本中,用于获取和填充这些属性的底层实现被泛化以支持大多数后端,而在 1.4 版本中,它们仅由psycopg2驱动程序支持。
参数:
-
cols– 可选的列键名列表或Column,作为过滤器用于将要获取的列。 -
supplemental_cols–可选的 RETURNING 表达式列表,与
UpdateBase.returning()方法传递的形式相同。当存在时,额外的列将包含在 RETURNING 子句中,并且在返回时,CursorResult对象将被“倒带”,以便像CursorResult.all()这样的方法将以大部分方式返回新行,就好像语句直接使用了UpdateBase.returning()。但是,与直接使用UpdateBase.returning()时不同,列的顺序是未定义的,因此只能使用名称或Row._mapping键来定位它们;它们不能可靠地以位置为目标。2.0 版本中新增。
-
sort_by_parameter_order–对于正在针对多个参数集执行的批量插入,组织返回的 RETURNING 结果,使返回的行与传递的参数集的顺序相对应。这仅适用于支持方言的 executemany 执行,并且通常利用 insertmanyvalues 功能。
2.0.10 版本中新增。
另请参阅
将返回的行与参数集相关联 - 关于批量插入的返回行排序的背景知识
另请参阅
UpdateBase.returning()
CursorResult.returned_defaults
CursorResult.returned_defaults_rows
CursorResult.inserted_primary_key
CursorResult.inserted_primary_key_rows
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
向该语句添加一个 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
该方法可以多次调用以向要返回的表达式列表添加新条目。
从版本 1.4.0b2 开始新添加:该方法可以多次调用以向要返回的表达式列表添加新条目。
给定的列表达式集合应该来源于作为 INSERT、UPDATE 或 DELETE 目标的表。虽然 Column 对象很典型,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在编译时,RETURNING 子句或数据库等效项将在语句内呈现。对于 INSERT 和 UPDATE,这些值是新插入/更新的值。对于 DELETE,这些值是被删除的行的值。
在执行时,要返回的列的值通过结果集可用,并且可以使用 CursorResult.fetchone() 等进行迭代。对于不本地支持返回值的 DBAPI(即 cx_oracle),SQLAlchemy 将在结果级别上近似此行为,以便提供合理数量的行为中立性。
请注意,并非所有数据库/DBAPI 都支持 RETURNING。对于没有支持的后端,在编译和/或执行时会引发异常。对于支持的后端,跨后端的功能差异很大,包括对 executemany() 和其他返回多行的语句的限制。请阅读正在使用的数据库的文档说明,以确定 RETURNING 的可用性。
参数:
-
*cols– 一系列列、SQL 表达式或整个表实体,要返回。 -
sort_by_parameter_order–对于正在执行针对多个参数集的批量 INSERT,组织 RETURNING 的结果,以便返回的行与传入的参数集的顺序对应。这仅适用于对支持的方言执行的 executemany 操作,通常利用 insertmanyvalues 功能。
从版本 2.0.10 开始新添加。
另请参阅
将 RETURNING 行相关联到参数集 - 对批量 INSERT 的 RETURNING 行排序的背景信息(核心级别讨论)
将 RETURNING 记录与输入数据顺序相关联 - 与 ORM 大批量 INSERT 语句 使用示例(ORM 级别讨论)
另请参阅
UpdateBase.return_defaults() - 针对单行 INSERT 或 UPDATE,针对高效获取服务器端默认值和触发器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程 中
attribute returning_column_descriptions
返回此 DML 构造体返回的列的 插件启用 描述,换句话说,作为 UpdateBase.returning() 的一部分建立的表达式。
当使用 ORM 时,此属性通常很有用,因为返回的扩展结构包含有关映射实体的信息。该部分 从 ORM 启用的 SELECT 和 DML 语句中检查实体和列 包含更多背景信息。
对于核心语句,此访问器返回的结构源自与 UpdateBase.exported_columns 访问器返回的相同对象:
>>> stmt = insert(user_table).returning(user_table.c.id, user_table.c.name)
>>> stmt.entity_description
[
{
"name": "id",
"type": Integer,
"expr": Column("id", Integer(), table=<user>, ...)
},
{
"name": "name",
"type": String(),
"expr": Column("name", String(), table=<user>, ...)
},
]
版本 1.4.33 中的新功能。
另请参阅
UpdateBase.entity_description
Select.column_descriptions - 用于 select() 构造的实体信息
从 ORM 启用的 SELECT 和 DML 语句中检查实体和列 - ORM 背景
method with_dialect_options(**opt: Any) → Self
将方言选项添加到此 INSERT/UPDATE/DELETE 对象中。
例如:
upd = table.update().dialect_options(mysql_limit=10)
method with_hint(text: str, selectable: _DMLTableArgument | None = None, dialect_name: str = '*') → Self
将单个表的表提示添加到此 INSERT/UPDATE/DELETE 语句中。
注意
UpdateBase.with_hint() 目前仅适用于 Microsoft SQL Server。对于 MySQL INSERT/UPDATE/DELETE 提示,请使用 UpdateBase.prefix_with()。
提示文本在使用的数据库后端的适当位置呈现,与此语句的主题 Table 相对应,或者可选地,相对于传递为 selectable 参数的给定 Table。
dialect_name选项将限制特定后端的特定提示的呈现。例如,要添加一个仅在 SQL Server 中生效的提示:
mytable.insert().with_hint("WITH (PAGLOCK)", dialect_name="mssql")
参数:
-
text– 提示的文本。 -
selectable– 可选的Table,指定在 UPDATE 或 DELETE 中作为提示主题的 FROM 子句的元素 - 仅适用于某些后端。 -
dialect_name– 默认为*,如果指定为特定方言的名称,将仅在使用该方言时应用这些提示。
class sqlalchemy.sql.expression.ValuesBase
为 INSERT 和 UPDATE 构造提供对ValuesBase.values()的支持。
成员
select, values()
类签名
类sqlalchemy.sql.expression.ValuesBase (sqlalchemy.sql.expression.UpdateBase)
attribute select: Select[Any] | None = None
用于 INSERT .. FROM SELECT 的 SELECT 语句
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
为 INSERT 语句指定一个固定的 VALUES 子句,或者为 UPDATE 指定 SET 子句。
请注意,Insert和Update构造支持基于传递给Connection.execute()的参数对 VALUES 和/或 SET 子句进行每次执行时的格式化。但是,ValuesBase.values()方法可用于将特定一组参数“固定”到语句中。
对ValuesBase.values()的多次调用将产生一个新的构造,每个构造的参数列表都会修改以包含发送的新参数。在单个参数字典的典型情况下,新传递的键将替换先前构造中的相同键。在基于列表的“多个值”构造的情况下,每个新值列表都会扩展到现有值列表上。
参数:
-
**kwargs–表示要映射到 VALUES 或 SET 子句中的值的
Column的字符串键值对:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name") -
*args–作为传递键/值参数的替代方案,可以将字典、元组或字典列表或元组作为单个位置参数传递,以形成语句的 VALUES 或 SET 子句。接受的形式因是
Insert还是Update构造而异。对于
Insert或Update构造,可以传递一个单独的字典,其工作方式与 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})对于任何形式,但更典型的是
Insert构造,也可以接受包含表中每一列条目的元组:users.insert().values((5, "some name"))Insert构造还支持传递一个字典列表或完整表元组,服务器上将呈现较不常见的 SQL 语法“多个值” - 此语法在后端(如 SQLite、PostgreSQL、MySQL)上受支持,但不一定适用于其他后端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])上述形式将呈现类似于多个 VALUES 语句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)需要注意的是传递多个值并不等同于使用传统的 executemany()形式。上述语法是一种特殊的语法,通常不常用。要对多行发出 INSERT 语句,正常方法是将多个值列表传递给
Connection.execute()方法,这种方法受到所有数据库后端的支持,并且对于非常大量的参数通常更有效率。另请参阅
发送多个参数 - 介绍了用于 INSERT 和其他语句的传统 Core 方法的多参数集调用。
UPDATE 构造还支持按特定顺序呈现 SET 参数。有关此功能,请参考
Update.ordered_values()方法。另请参阅
Update.ordered_values()
DML 基础构造
顶层“INSERT”、“UPDATE”、“DELETE”构造函数。
| 对象名称 | 描述 |
|---|---|
| delete(table) | 构造Delete对象。 |
| insert(table) | 构造一个Insert对象。 |
| 更新(table) | 构造一个Update对象。 |
function sqlalchemy.sql.expression.delete(table: _DMLTableArgument) → Delete
构造Delete对象。
例如:
from sqlalchemy import delete
stmt = (
delete(user_table).
where(user_table.c.id == 5)
)
类似功能也可通过TableClause.delete()方法在Table上获得。
参数:
table – 要从中删除行的表。
另请参阅
使用 UPDATE 和 DELETE 语句 - 在 SQLAlchemy 统一教程中
function sqlalchemy.sql.expression.insert(table: _DMLTableArgument) → Insert
构造一个Insert对象。
例如:
from sqlalchemy import insert
stmt = (
insert(user_table).
values(name='username', fullname='Full Username')
)
类似功能也可通过TableClause.insert()方法在Table上获得。
另请参阅
使用 INSERT 语句 - 在 SQLAlchemy 统一教程中
参数:
-
table–TableClause,即插入主题。 -
values– 要插入的值集合;请参阅Insert.values()以获取此处允许的格式描述。可以完全省略;Insert构造还将根据传递给Connection.execute()的参数,在执行时动态渲染 VALUES 子句。 -
inline– 如果为 True,则不会尝试检索生成的 SQL 默认值,以便在语句中提供;特别地,这允许 SQL 表达式在语句中“内联”渲染,而无需事先执行它们;对于支持“返回”的后端,这会关闭语句的“隐式返回”功能。
如果同时存在insert.values和编译时绑定参数,则编译时绑定参数将覆盖在insert.values中指定的信息,按键分别覆盖。
Insert.values 中的键可以是 Column 对象或它们的字符串标识符。 每个键可能引用以下之一:
-
一个字面数据值(即字符串、数字等);
-
一个 Column 对象;
-
一个 SELECT 语句。
如果指定了一个 SELECT 语句,该语句引用了此 INSERT 语句的表,那么该语句将与 INSERT 语句相关联。
另请参阅
使用 INSERT 语句 - 在 SQLAlchemy 统一教程 中
function sqlalchemy.sql.expression.update(table: _DMLTableArgument) → Update
构造一个 Update 对象。
例如:
from sqlalchemy import update
stmt = (
update(user_table).
where(user_table.c.id == 5).
values(name='user #5')
)
类似功能也可通过 TableClause.update() 方法在 Table 上获得。
参数:
table – 代表要更新的数据库表的 Table 对象。
另请参阅
使用 UPDATE 和 DELETE 语句 - 在 SQLAlchemy 统一教程 中
DML 类文档构造函数
DML Foundational Constructors 中列出的构造函数的类文档。
| 对象名称 | 描述 |
|---|---|
| Delete | 代表一个 DELETE 结构。 |
| Insert | 代表一个 INSERT 结构。 |
| Update | 代表一个 Update 结构。 |
| UpdateBase | 形成 INSERT、UPDATE 和 DELETE 语句的基础。 |
| ValuesBase | 为 INSERT 和 UPDATE 结构提供 ValuesBase.values() 的支持。 |
class sqlalchemy.sql.expression.Delete
代表一个 DELETE 结构。
Delete 对象是使用 delete() 函数创建的。
成员
where(), returning()
类签名
类sqlalchemy.sql.expression.Delete(sqlalchemy.sql.expression.DMLWhereBase,sqlalchemy.sql.expression.UpdateBase)
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
继承自 DMLWhereBase 的 DMLWhereBase.where() 方法
返回一个新的构造,其中给定的表达式被添加到其 WHERE 子句中,并通过 AND 连接到现有子句(如果有)。
Update.where() 和 Delete.where() 都支持多表形式,包括特定于数据库的UPDATE...FROM以及DELETE..USING。对于不支持多表的后端,使用多表的跨后端方法是利用相关子查询。请参阅下面链接的教程部分以获取示例。
另请参见
相关更新
UPDATE..FROM
多表删除
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
继承自 UpdateBase.returning() 方法的 UpdateBase
为该语句添加一个 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
可以多次调用该方法以向要返回的表达式列表中添加新条目。
从版本 1.4.0b2 开始:可以多次调用该方法以向要返回的表达式列表中添加新条目。
给定的列表达式集合应源自 INSERT、UPDATE 或 DELETE 的目标表。虽然Column对象是典型的,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在编译时,将在语句中呈现 RETURNING 子句或数据库等效。对于 INSERT 和 UPDATE,值是新插入/更新的值。对于 DELETE,值是被删除的行的值。
在执行时,要返回的列的值通过结果集提供,并可以使用CursorResult.fetchone()等进行迭代。对于不原生支持返回值的 DBAPI(即 cx_oracle),SQLAlchemy 将在结果级别近似此行为,以便提供合理数量的行为中立性。
请注意,并非所有数据库/DBAPI 都支持 RETURNING。对于那些不支持的后端,在编译和/或执行时会引发异常。对于支持它的后端,跨后端的功能差异很大,包括对 executemany()和返回多行的其他语句的限制。请阅读所使用数据库的文档注释,以确定 RETURNING 的可用性。
参数:
-
*cols– 要返回的一系列列、SQL 表达式或整个表实体。 -
sort_by_parameter_order–对于针对多个参数集执行的批量插入,组织 RETURNING 的结果,使返回的行与传入的参数集的顺序对应。这仅适用于支持方言的 executemany 执行,并通常利用 insertmanyvalues 功能。
版本 2.0.10 中的新功能。
另请参阅
将 RETURNING 行与参数集相关联 - 关于批量插入 RETURNING 行排序的背景(核心级别讨论)
将 RETURNING 记录与输入数据顺序相关联 - 与 ORM 批量 INSERT 语句 的使用示例(ORM 级别讨论)
另请参阅
UpdateBase.return_defaults() - 一种针对单行 INSERT 或 UPDATE 的有效获取服务器端默认值和触发器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程 中
class sqlalchemy.sql.expression.Insert
表示一个 INSERT 构造。
Insert 对象是使用 insert() 函数创建的。
成员
values(), returning(), from_select(), inline(), select
类签名
类 sqlalchemy.sql.expression.Insert(sqlalchemy.sql.expression.ValuesBase)
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
继承自 ValuesBase.values() 方法的 ValuesBase
为 INSERT 语句指定固定的 VALUES 子句,或为 UPDATE 指定 SET 子句。
请注意,Insert和Update构造支持基于传递给Connection.execute()的参数对 VALUES 和/或 SET 子句进行执行时格式化。但是,ValuesBase.values()方法可用于将特定一组参数“固定”到语句中。
多次调用ValuesBase.values()将生成一个新构造,每个构造的参数列表都会修改以包含发送的新参数。在典型情况下,单个参数字典中的新传递键将替换先前构造中的相同键。在基于列表的“多个值”构造的情况下,每个新值列表都会扩展到现有值列表上。
参数:
-
**kwargs–键值对表示
Column的字符串键映射到要呈现到 VALUES 或 SET 子句中的值:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name") -
*args–作为传递键/值参数的替代方案,可以将字典、元组或字典或元组的列表作为单个位置参数传递,以形成语句的 VALUES 或 SET 子句。接受的形式因此是一个
Insert还是一个Update构造而异。对于
Insert或Update构造,可以传递一个字典,其工作方式与 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})对于任何形式,但更典型地用于
Insert构造,也接受包含表中每列条目的元组:users.insert().values((5, "some name"))Insert构造还支持传递字典或完整表元组的列表,这在服务器上将呈现较少见的 SQL 语法“多个值” - 此语法在后端(如 SQLite、PostgreSQL、MySQL)上受支持,但不一定在其他后端上受支持:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])上述形式将呈现类似于多个 VALUES 语句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)必须注意传递多个值并不等同于使用传统的 executemany()形式。上述语法是一种特殊的语法,通常不常用。要针对多行发出 INSERT 语句,正常方法是将多个值列表传递给
Connection.execute()方法,该方法受到所有数据库后端支持,并且对于非常大量的参数通常更有效率。另请参阅
发送多个参数 - 介绍传统核心方法的多参数集调用,用于 INSERT 和其他语句。
UPDATE 结构还支持按特定顺序呈现 SET 参数。有关此功能,请参考
Update.ordered_values()方法。另请参阅
Update.ordered_values()
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
继承自 UpdateBase.returning() 方法的 UpdateBase
在此语句中添加一个 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
可以多次调用该方法以向要返回的表达式列表添加新条目。
从版本 1.4.0b2 中新增:可以多次调用该方法以向要返回的表达式列表添加新条目。
给定的列表达式集合应源自 INSERT、UPDATE 或 DELETE 的目标表。虽然Column对象是典型的,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在编译时,将在语句中呈现一个 RETURNING 子句,或者数据库等效项。对于 INSERT 和 UPDATE,这些值是新插入/更新的值。对于 DELETE,这些值是被删除的行的值。
在执行时,要返回的列的值通过结果集提供,并可以使用CursorResult.fetchone()等进行迭代。对于不本地支持返回值的 DBAPI(即 cx_oracle),SQLAlchemy 将在结果级别近似此行为,以便提供合理数量的行为中立性。
请注意,并非所有数据库/DBAPI 都支持 RETURNING。对于那些不支持的后端,在编译和/或执行时会引发异常。对于那些支持它的后端,跨后端的功能差异很大,包括对 executemany()和其他返回多行的语句的限制。请阅读正在使用的数据库的文档说明,以确定 RETURNING 的可用性。
参数:
-
*cols– 一系列列、SQL 表达式或整个表实体要返回。 -
sort_by_parameter_order–对于正在针对多个参数集执行的批量 INSERT,组织 RETURNING 的结果,使返回的行与传入的参数集的顺序对应。这仅适用于支持方言的 executemany 执行,并通常利用 insertmanyvalues 功能。
2.0.10 版中的新功能。
另请参阅
将 RETURNING 行与参数集相关联 - 关于批量 INSERT 的 RETURNING 行排序的背景(核心级别讨论)
将 RETURNING 记录与输入数据顺序相关联 - 与 ORM 批量 INSERT 语句一起使用的示例(ORM 级别讨论)
另请参阅
UpdateBase.return_defaults() - 一种针对高效获取服务器端默认值和触发器的单行 INSERT 或 UPDATE 的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程中
method from_select(names: Sequence[_DMLColumnArgument], select: Selectable, include_defaults: bool = True) → Self
返回一个新的Insert构造,表示一个INSERT...FROM SELECT语句。
例如:
sel = select(table1.c.a, table1.c.b).where(table1.c.c > 5)
ins = table2.insert().from_select(['a', 'b'], sel)
参数:
-
names– 一系列字符串列名或Column对象,表示目标列。 -
select– 一个select()构造,FromClause或其他解析为FromClause的构造,例如 ORMQuery对象等。从此 FROM 子句返回的列的顺序应与作为names参数发送的列的顺序相对应;虽然在传递给数据库之前不会检查这一点,但如果这些列列表不对应,数据库通常会引发异常。 -
include_defaults–如果为 True,则将渲染到 INSERT 和 SELECT 语句中的非服务器默认值和在
Column对象上指定的 SQL 表达式(如 Column INSERT/UPDATE Defaults 中所记录)未在名称列表中另行指定,以便这些值也包含在要插入的数据中。注意
使用 Python 可调用函数的 Python 端默认值将仅在整个语句中被调用 一次,而不是每行一次。
method inline() → Self
将此 Insert 构造“内联”。
当设置时,将不会尝试检索在语句中提供的 SQL 生成的默认值;特别是,这允许 SQL 表达式在语句中“内联”渲染,无需事先对它们进行预执行;对于支持“returning”的后端,这将关闭语句的“隐式返回”功能。
在版本 1.4 中进行了更改:Insert.inline 参数现已被 Insert.inline() 方法取代。
attribute select: Select[Any] | None = None
INSERT .. FROM SELECT 的 SELECT 语句
class sqlalchemy.sql.expression.Update
表示一个 Update 构造。
使用 update() 函数创建 Update 对象。
成员
returning(), where(), values(), inline(), ordered_values()
类签名
类 sqlalchemy.sql.expression.Update(sqlalchemy.sql.expression.DMLWhereBase,sqlalchemy.sql.expression.ValuesBase)
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
继承自 UpdateBase.returning() 方法的 UpdateBase
向该语句添加一个 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
此方法可以多次调用以向要返回的表达式列表添加新条目。
新版本 1.4.0b2 中:此方法可以多次调用以向要返回的表达式列表添加新条目。
给定的列表达式集合应源自是 INSERT、UPDATE 或 DELETE 目标的表。虽然 Column 对象是典型的,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
编译时,RETURNING 子句或数据库等效项将包含在语句中。对于 INSERT 和 UPDATE,这些值是新插入/更新的值。对于 DELETE,这些值是被删除行的值。
在执行时,要返回的列的值通过结果集提供,并可以使用 CursorResult.fetchone() 和类似方法进行迭代。对于不原生支持返回值的 DBAPI(即 cx_oracle 等),SQLAlchemy 将在结果级别近似此行为,以提供合理数量的行为中立性。
请注意,并非所有数据库/DBAPI 都支持 RETURNING。对于那些没有支持的后端,在编译和/或执行时会引发异常。对于支持的后端,跨后端的功能差异很大,包括对 executemany() 和其他返回多行的语句的限制。请阅读使用中的数据库的文档注释,以确定 RETURNING 的可用性。
参数:
-
*cols– 一系列要返回的列、SQL 表达式或整个表实体。 -
sort_by_parameter_order–对于正在执行多个参数集的批量 INSERT,组织 RETURNING 的结果,使返回的行与传入的参数集的顺序对应。这仅适用于支持的方言的 executemany 执行,并且通常利用 insertmanyvalues 功能。
在 2.0.10 版本中新增。
另请参阅
将 RETURNING 行与参数集相关联 - 关于批量插入 RETURNING 行排序的背景(核心层讨论)
将 RETURNING 记录与输入数据顺序相关联 - 在 ORM 批量 INSERT 语句 中的使用示例(ORM 层讨论)
另请参阅
UpdateBase.return_defaults() - 针对高效获取单行 INSERT 或 UPDATE 的服务器端默认值和触发器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程 中
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self
从 DMLWhereBase.where() 方法的 DMLWhereBase 继承
返回一个新的构造,其中包含要添加到其 WHERE 子句中的给定表达式,如果有的话,通过 AND 连接到现有子句。
Update.where()和Delete.where()都支持多表形式,包括数据库特定的UPDATE...FROM以及DELETE..USING。 对于不支持多表的后端,使用多表的后端不可知方法是利用相关子查询。 有关示例,请参阅下面链接的教程部分。
亦见
相关更新
UPDATE..FROM
多表删除
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
继承自 ValuesBase.values() 方法的 ValuesBase
为 INSERT 语句指定一个固定的 VALUES 子句,或者为 UPDATE 指定 SET 子句。
请注意,Insert和Update构造支持基于传递给Connection.execute()的参数对 VALUES 和/或 SET 子句进行每次执行时间格式化。 但是,ValuesBase.values()方法可用于将特定参数集固定到语句中。
多次调用ValuesBase.values()将产生一个新的构造,每个构造都将参数列表修改为包含新发送的参数。 在单个参数字典的典型情况下,新传递的键将替换先前构造中的相同键。 在基于列表的“多值”构造的情况下,每个新值列表都被扩展到现有值列表上。
参数:
-
**kwargs–表示将映射到要渲染到 VALUES 或 SET 子句中的值的
Column的字符串键值对:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name") -
*args–作为传递键/值参数的替代方案,可以将字典、元组或字典或元组的列表作为单个位置参数传递,以形成语句的 VALUES 或 SET 子句。被接受的形式因为是
Insert还是Update构造而异。对于
Insert或Update构造,可以传递单个字典,其效果与 kwargs 形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})对于任何形式,但更常见的是
Insert构造,也可以接受包含表中每一列条目的元组:users.insert().values((5, "some name"))Insert构造还支持传递字典或完整表元组的列表,这将在服务器上呈现较少使用的 SQL 语法 "多个值" - 此语法受到后端(如 SQLite、PostgreSQL、MySQL)的支持,但不一定适用于其他后端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])上述形式将呈现类似于多个 VALUES 语句:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)必须注意 传递多个值并不等同于使用传统的 executemany() 形式。上述语法是一种 特殊 的语法,通常不使用。要针对多行发出 INSERT 语句,正常的方法是将多个值列表传递给
Connection.execute()方法,这受到所有数据库后端的支持,并且对于非常大量的参数通常更有效率。另请参阅
发送多个参数 - 介绍了传统的 Core 方法,用于 INSERT 和其他语句的多参数集调用。
UPDATE 构造还支持按特定顺序渲染 SET 参数。有关此功能,请参阅
Update.ordered_values()方法。另请参阅
Update.ordered_values()
method inline() → Self
使此 Update 构造 "内联"。
当设置时,通过default关键字在Column对象上存在的 SQL 默认值将被编译为语句中的‘inline’并且不会预先执行。这意味着它们的值不会出现在CursorResult.last_updated_params()返回的字典中。
在 1.4 版本中更改:update.inline参数现已由Update.inline()方法取代。
method ordered_values(*args: Tuple[_DMLColumnArgument, Any]) → Self
使用显式参数排序指定此 UPDATE 语句的 VALUES 子句,在结果 UPDATE 语句的 SET 子句中将保持该顺序。
例如:
stmt = table.update().ordered_values(
("name", "ed"), ("ident", "foo")
)
另请参阅
参数有序更新 - Update.ordered_values()方法的完整示例。
在 1.4 版本中更改:Update.ordered_values()方法取代了update.preserve_parameter_order参数,该参数将在 SQLAlchemy 2.0 中移除。
class sqlalchemy.sql.expression.UpdateBase
为INSERT、UPDATE和DELETE语句提供基础。
成员
entity_description, exported_columns, params(), return_defaults(), returning(), returning_column_descriptions, with_dialect_options(), with_hint()
类签名
类sqlalchemy.sql.expression.UpdateBase (sqlalchemy.sql.roles.DMLRole, sqlalchemy.sql.expression.HasCTE, sqlalchemy.sql.expression.HasCompileState, sqlalchemy.sql.base.DialectKWArgs, sqlalchemy.sql.expression.HasPrefixes, sqlalchemy.sql.expression.Generative, sqlalchemy.sql.expression.ExecutableReturnsRows, sqlalchemy.sql.expression.ClauseElement)
attribute entity_description
返回此 DML 结构操作的表和/或实体的插件启用描述。
当使用 ORM 时,此属性通常很有用,因为它返回一个扩展结构,其中包含有关映射实体的信息。从 ORM 启用的 SELECT 和 DML 语句中检查实体和列部分提供了更多背景信息。
对于 Core 语句,此访问器返回的结构源自UpdateBase.table属性,并引用正在插入、更新或删除的Table:
>>> stmt = insert(user_table)
>>> stmt.entity_description
{
"name": "user_table",
"table": Table("user_table", ...)
}
版本 1.4.33 中的新功能。
请参阅
UpdateBase.returning_column_descriptions
Select.column_descriptions - select()构造的实体信息
从 ORM 启用的 SELECT 和 DML 语句中检查实体和列 - ORM 背景
attribute exported_columns
将 RETURNING 列作为此语句的列集合返回。
版本 1.4 中的新功能。
method params(*arg: Any, **kw: Any) → NoReturn
设置语句的参数。
此方法在基类上引发NotImplementedError,并由ValuesBase覆盖,以提供 UPDATE 和 INSERT 的 SET/VALUES 子句。
method return_defaults(*cols: _DMLColumnArgument, supplemental_cols: Iterable[_DMLColumnArgument] | None = None, sort_by_parameter_order: bool = False) → Self
仅支持后端,使用 RETURNING 子句以获取服务器端表达式和默认值。
深度炼金术
UpdateBase.return_defaults() 方法被 ORM 用于其内部工作中,以获取新生成的主键和服务器默认值,特别是为了提供Mapper.eager_defaults ORM 特性的基础实现,以及允许批量 ORM 插入时的 RETURNING 支持。它的行为相当特殊,实际上并不打算用于一般用途。终端用户应该坚持使用UpdateBase.returning() 来添加 RETURNING 子句到他们的 INSERT、UPDATE 和 DELETE 语句中。
通常情况下,单行 INSERT 语句在执行时会自动填充CursorResult.inserted_primary_key 属性,该属性以Row 对象的形式存储刚刚插入的行的主键,其中列名作为命名元组键(并且Row._mapping 视图也被完全填充)。正在使用的方言选择用于填充这些数据的策略;如果它是使用服务器端默认值和/或 SQL 表达式生成的,则通常会使用方言特定的方法,如cursor.lastrowid或RETURNING 来获取新的主键值。
然而,当在执行语句之前通过调用UpdateBase.return_defaults()对语句进行修改时,仅对支持 RETURNING 的后端以及将Table.implicit_returning参数保持其默认值True的Table对象发生附加行为。在这些情况下,当从语句的执行返回CursorResult时,不仅CursorResult.inserted_primary_key像往常一样被填充,CursorResult.returned_defaults属性还将被填充为一个命名为Row的元组,代表该单行的所有服务器生成的值的完整范围,包括任何指定Column.server_default或使用 SQL 表达式的Column.default的列的值。
当使用 insertmanyvalues 来调用具有多行的 INSERT 语句时,UpdateBase.return_defaults()修饰符将导致CursorResult.inserted_primary_key_rows和CursorResult.returned_defaults_rows属性完全填充,其中包含代表新插入的主键值以及每行插入的新生成的服务器值的Row对象的列表。CursorResult.inserted_primary_key和CursorResult.returned_defaults属性也将继续填充这两个集合的第一行。
如果后端不支持 RETURNING,或者正在使用的 Table 禁用了 Table.implicit_returning,则不会添加 RETURNING 子句,也不会获取额外数据,但 INSERT、UPDATE 或 DELETE 语句会正常执行。
例如:
stmt = table.insert().values(data='newdata').return_defaults()
result = connection.execute(stmt)
server_created_at = result.returned_defaults['created_at']
当针对 UPDATE 语句使用 UpdateBase.return_defaults() 时,会查找包含 Column.onupdate 或 Column.server_onupdate 参数的列,用于构建默认情况下将包含在 RETURNING 子句中的列(如果未显式指定列)。当针对 DELETE 语句使用时,默认情况下不包含任何列在 RETURNING 中,而必须显式指定,因为在 DELETE 语句进行时通常不会更改值的列。
新功能在版本 2.0 中:UpdateBase.return_defaults() 现在也支持 DELETE 语句,并且已经从 ValuesBase 移动到 UpdateBase。
UpdateBase.return_defaults() 方法与 UpdateBase.returning() 方法是互斥的,如果同时在一个语句上使用了两者,将在 SQL 编译过程中引发错误。因此,INSERT、UPDATE 或 DELETE 语句的 RETURNING 子句只由其中一个方法控制。
UpdateBase.return_defaults() 方法与 UpdateBase.returning() 的不同之处在于:
-
UpdateBase.return_defaults()方法导致CursorResult.returned_defaults集合被填充为 RETURNING 结果的第一行。当使用UpdateBase.returning()时,此属性不会被填充。 -
UpdateBase.return_defaults()与用于获取自动生成的主键值并将其填充到CursorResult.inserted_primary_key属性的现有逻辑兼容。相比之下,使用UpdateBase.returning()将导致CursorResult.inserted_primary_key属性保持未填充。 -
UpdateBase.return_defaults()可以针对任何后端调用。不支持 RETURNING 的后端将跳过该功能的使用,而不是引发异常,除非传递了supplemental_cols。对于不支持 RETURNING 或目标Table设置Table.implicit_returning为False的后端,CursorResult.returned_defaults的返回值将为None。 -
使用
executemany()调用的 INSERT 语句在后端数据库驱动程序支持 insertmanyvalues 功能的情况下得到支持,这个功能现在大多数包含在 SQLAlchemy 中的后端都支持。当使用executemany时,CursorResult.returned_defaults_rows和CursorResult.inserted_primary_key_rows访问器将返回插入的默认值和主键。1.4 版中的新功能:添加了
CursorResult.returned_defaults_rows和CursorResult.inserted_primary_key_rows访问器。在 2.0 版中,为这些属性提取和填充数据的底层实现被泛化以受到大多数后端的支持,而在 1.4 版中,它们仅受到psycopg2驱动程序的支持。
参数:
-
cols– 可选的列键名或Column列表,充当将被提取的列的过滤器。 -
supplemental_cols–可选的 RETURNING 表达式列表,与传递给
UpdateBase.returning()方法的形式相同。当存在时,额外的列将包含在 RETURNING 子句中,并且在返回时CursorResult对象将被“倒带”,因此像CursorResult.all()这样的方法将返回新的行,几乎就像语句直接使用了UpdateBase.returning()一样。但是,与直接使用UpdateBase.returning()不同,列的顺序是未定义的,因此只能使用名称或Row._mapping键进行定位;它们不能可靠地按位置进行定位。2.0 版中的新功能。
-
sort_by_parameter_order–对于针对多个参数集执行的批量插入,组织 RETURNING 的结果,使返回的行与传入的参数集的顺序对应。这仅适用于支持方言的 executemany 执行,并通常利用 insertmanyvalues 特性。
2.0.10 版中的新功能。
另请参阅
将 RETURNING 行与参数集相关联 - 关于对批量插入的 RETURNING 行进行排序的背景信息
另请参阅
UpdateBase.returning()
CursorResult.returned_defaults
CursorResult.returned_defaults_rows
CursorResult.inserted_primary_key
CursorResult.inserted_primary_key_rows
method returning(*cols: _ColumnsClauseArgument[Any], sort_by_parameter_order: bool = False, **_UpdateBase__kw: Any) → UpdateBase
为该语句添加 RETURNING 或等效子句。
例如:
>>> stmt = (
... table.update()
... .where(table.c.data == "value")
... .values(status="X")
... .returning(table.c.server_flag, table.c.updated_timestamp)
... )
>>> print(stmt)
UPDATE some_table SET status=:status
WHERE some_table.data = :data_1
RETURNING some_table.server_flag, some_table.updated_timestamp
该方法可以多次调用以将新条目添加到要返回的表达式列表中。
新版本 1.4.0b2 中添加:该方法可以多次调用以将新条目添加到要返回的表达式列表中。
给定的列表达式集应源自于 INSERT、UPDATE 或 DELETE 的目标表。虽然Column对象是典型的,但元素也可以是表达式:
>>> stmt = table.insert().returning(
... (table.c.first_name + " " + table.c.last_name).label("fullname")
... )
>>> print(stmt)
INSERT INTO some_table (first_name, last_name)
VALUES (:first_name, :last_name)
RETURNING some_table.first_name || :first_name_1 || some_table.last_name AS fullname
在编译时,RETURNING 子句或数据库等效子句将在语句内呈现。对于 INSERT 和 UPDATE,值是新插入/更新的值。对于 DELETE,值是已删除行的值。
在执行时,要返回的列的值通过结果集可用,并且可以使用CursorResult.fetchone()等进行迭代。对于不本地支持返回值的 DBAPI(即 cx_oracle),SQLAlchemy 将在结果级别近似此行为,以便提供合理数量的行为中立性。
注意,并非所有的数据库/DBAPI 都支持 RETURNING。对于不支持的后端,在编译和/或执行时会引发异常。对于支持它的后端,跨后端的功能差异很大,包括对 executemany()和其他返回多行的语句的限制。请阅读所使用数据库的文档注释,以确定 RETURNING 的可用性。
参数:
-
*cols– 一系列列、SQL 表达式或整个表实体将被返回。 -
sort_by_parameter_order–对于针对多个参数集执行的批量 INSERT,请组织 RETURNING 的结果,使返回的行与传递的参数集的顺序相对应。这仅适用于支持方言的 executemany 执行,并通常利用 insertmanyvalues 功能。
新版本中添加的 2.0.10。
另请参阅
将 RETURNING 行与参数集相关联 - 关于对批量 INSERT 排序 RETURNING 行的背景(核心级讨论)
将 RETURNING 记录与输入数据顺序相关联 - 与 ORM Bulk INSERT Statements 的使用示例(ORM 级讨论)
另请参阅
UpdateBase.return_defaults() - 一种针对单行 INSERTs 或 UPDATEs 的有效提取服务器端默认值和触发器的替代方法。
INSERT…RETURNING - 在 SQLAlchemy 统一教程 中
attribute returning_column_descriptions
返回此 DML 构造与之相对应的列的 插件启用 描述,换句话说,作为 UpdateBase.returning() 的一部分建立的表达式。
当使用 ORM 时,此属性通常很有用,因为它返回了一个包含有关映射实体信息的扩展结构。该部分 从启用 ORM 的 SELECT 和 DML 语句检查实体和列 包含了更多的背景知识。
对于 Core 语句,此访问器返回的结构源自与 UpdateBase.exported_columns 访问器返回的相同对象:
>>> stmt = insert(user_table).returning(user_table.c.id, user_table.c.name)
>>> stmt.entity_description
[
{
"name": "id",
"type": Integer,
"expr": Column("id", Integer(), table=<user>, ...)
},
{
"name": "name",
"type": String(),
"expr": Column("name", String(), table=<user>, ...)
},
]
从版本 1.4.33 开始新添加。
另请参阅
UpdateBase.entity_description
Select.column_descriptions - 一个 select() 构造的实体信息
从启用 ORM 的 SELECT 和 DML 语句检查实体和列 - ORM 背景
method with_dialect_options(**opt: Any) → Self
为这个 INSERT/UPDATE/DELETE 对象添加方言选项。
例如:
upd = table.update().dialect_options(mysql_limit=10)
method with_hint(text: str, selectable: _DMLTableArgument | None = None, dialect_name: str = '*') → Self
为这个 INSERT/UPDATE/DELETE 语句添加一个单独的表提示。
注意
UpdateBase.with_hint() 目前仅适用于 Microsoft SQL Server。对于 MySQL INSERT/UPDATE/DELETE 提示,请使用 UpdateBase.prefix_with()。
提示文本根据正在使用的数据库后端在适当的位置呈现,相对于这个语句的主题 Table ,或者可选地传递给 Table 的 selectable 参数的 Table 。
dialect_name选项将限制特定提示的渲染到特定后端。例如,要添加仅在 SQL Server 上生效的提示:
mytable.insert().with_hint("WITH (PAGLOCK)", dialect_name="mssql")
参数:
-
text– 提示的文本。 -
selectable– 可选的Table,指定 UPDATE 或 DELETE 中 FROM 子句的一个元素作为提示的主题 - 仅适用于某些后端。 -
dialect_name– 默认为*,如果指定为特定方言的名称,则仅在使用该方言时应用这些提示。
class sqlalchemy.sql.expression.ValuesBase
为ValuesBase.values()提供了对 INSERT 和 UPDATE 构造的支持。
成员
select, values()
类签名
类sqlalchemy.sql.expression.ValuesBase(sqlalchemy.sql.expression.UpdateBase)
attribute select: Select[Any] | None = None
INSERT .. FROM SELECT 的 SELECT 语句
method values(*args: _DMLColumnKeyMapping[Any] | Sequence[Any], **kwargs: Any) → Self
为 INSERT 语句指定一个固定的 VALUES 子句,或为 UPDATE 指定 SET 子句。
请注意,Insert和Update构造支持基于传递给Connection.execute()的参数对 VALUES 和/或 SET 子句进行执行时格式化。但是,ValuesBase.values()方法可用于将特定一组参数固定到语句中。
对ValuesBase.values()的多次调用将生成一个新的构造,每个构造的参数列表都修改为包括新发送的参数。在单个参数字典的典型情况下,新传递的键将替换上一个构造中的相同键。在基于列表的“多个值”构造的情况下,每个新值列表都会附加到现有的值列表上。
参数:
-
**kwargs–表示
Column的字符串键的键值对映射到要呈现到 VALUES 或 SET 子句中的值:users.insert().values(name="some name") users.update().where(users.c.id==5).values(name="some name") -
*args–作为传递键/值参数的替代方案,可以传递一个字典、元组或字典或元组的列表作为单个位置参数,以形成语句的 VALUES 或 SET 子句。接受的形式因此是一个
Insert或Update结构而异。对于
Insert或Update结构,可以传递单个字典,其工作方式与关键字参数形式相同:users.insert().values({"name": "some name"}) users.update().values({"name": "some new name"})同样适用于任何形式,但更典型的是对于
Insert结构,还可以接受一个包含表中每一列的条目的元组:users.insert().values((5, "some name"))Insert结构还支持传递字典或完整表元组的列表,这将在服务器上呈现较少见的 SQL 语法“多个值” - 此语法在后端,如 SQLite、PostgreSQL、MySQL 等中受支持,但不一定适用于其他后端:users.insert().values([ {"name": "some name"}, {"name": "some other name"}, {"name": "yet another name"}, ])上述形式将呈现类似于多个 VALUES 语句的内容:
INSERT INTO users (name) VALUES (:name_1), (:name_2), (:name_3)需要注意的是,传递多个值并不等同于使用传统的 executemany() 形式。上述语法是一种特殊的语法,通常不常用。要针对多行发出 INSERT 语句,正常方法是将多个值列表传递给
Connection.execute()方法,该方法受到所有数据库后端的支持,并且通常对于非常大量的参数更有效率。请参阅
发送多个参数 - 介绍了用于 INSERT 和其他语句的传统 Core 方法的多个参数集调用。
UPDATE 结构还支持以特定顺序呈现 SET 参数。有关此功能,请参阅
Update.ordered_values()方法。请参阅
Update.ordered_values()
SQL 和通用函数
通过使用 func 命名空间来调用 SQL 函数。请参阅 使用 SQL 函数 教程,了解如何使用 func 对象在语句中渲染 SQL 函数的背景知识。
另请参阅
使用 SQL 函数 - 在 SQLAlchemy 统一教程 中
函数 API
SQL 函数的基本 API,提供了 func 命名空间以及可用于可扩展性的类。
| 对象名称 | 描述 |
|---|---|
| AnsiFunction | 以“ansi”格式定义函数,不会渲染括号。 |
| Function | 描述一个命名的 SQL 函数。 |
| FunctionElement | SQL 函数导向构造的基类。 |
| GenericFunction | 定义一个‘通用’函数。 |
| register_function(identifier, fn[, package]) | 将可调用对象与特定函数名关联。 |
class sqlalchemy.sql.functions.AnsiFunction
以“ansi”格式定义函数,不会渲染括号。
类签名
类 sqlalchemy.sql.functions.AnsiFunction (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.Function
描述一个命名的 SQL 函数。
Function 对象通常由 func 生成对象生成。
参数:
-
*clauses– 形成 SQL 函数调用参数的列表达式列表。 -
type_– 可选的TypeEngine数据类型对象,将用作由此函数调用生成的列表达式的返回值。 -
packagenames–一个字符串,指示在生成 SQL 时要在函数名前添加的包前缀名称。当使用点格式调用
func生成器时会创建这些,例如:func.mypackage.some_function(col1, col2)
另请参阅
使用 SQL 函数 - 在 SQLAlchemy 统一教程 中
func - 产生注册或特设的 Function 实例的命名空间。
GenericFunction - 允许创建注册的函数类型。
成员
init()
类签名
类 sqlalchemy.sql.functions.Function (sqlalchemy.sql.functions.FunctionElement)
method __init__(name: str, *clauses: _ColumnExpressionOrLiteralArgument[Any], type_: _TypeEngineArgument[_T] | None = None, packagenames: Tuple[str, ...] | None = None)
构造一个 Function。
通常使用 func 构造函数来构造新的 Function 实例。
class sqlalchemy.sql.functions.FunctionElement
用于 SQL 函数导向构造的基础。
这是一个 通用类型,意味着类型检查器和 IDE 可以指示在此函数的 Result 中期望的类型。参见 GenericFunction 以了解如何执行此操作的示例。
另请参阅
使用 SQL 函数 - 在 SQLAlchemy 统一教程 中
Function - SQL 函数的命名。
func - 产生注册或特设的 Function 实例的命名空间。
GenericFunction - 允许创建注册的函数类型。
成员
init(), alias(), as_comparison(), c, clauses, column_valued(), columns, entity_namespace, exported_columns, filter(), over(), scalar_table_valued(), select(), self_group(), table_valued(), within_group(), within_group_type()
类签名
类sqlalchemy.sql.functions.FunctionElement(sqlalchemy.sql.expression.Executable,sqlalchemy.sql.expression.ColumnElement,sqlalchemy.sql.expression.FromClause,sqlalchemy.sql.expression.Generative)
method __init__(*clauses: _ColumnExpressionOrLiteralArgument[Any])
构建一个FunctionElement。
参数:
-
*clauses– 列表,包含形成 SQL 函数调用参数的列表达式。 -
**kwargs– 通常由子类消耗的额外 kwargs。
另请参阅
func
Function
method alias(name: str | None = None, joins_implicitly: bool = False) → TableValuedAlias
对这个FunctionElement构建一个别名。
提示
FunctionElement.alias() 方法是创建“表值”SQL 函数的机制的一部分。但是,大多数用例都通过FunctionElement上的更高级方法来处理,包括FunctionElement.table_valued()和FunctionElement.column_valued()。
此结构将函数包装在适合 FROM 子句的命名别名中,例如 PostgreSQL 所接受的风格。 还提供了使用特殊的 .column 属性的列表达式,该属性可用于在列或 where 子句中引用函数的输出,例如 PostgreSQL 等后端的标量值。
对于完整的表值表达式,请先使用 FunctionElement.table_valued() 方法来建立命名列。
例如:
>>> from sqlalchemy import func, select, column
>>> data_view = func.unnest([1, 2, 3]).alias("data_view")
>>> print(select(data_view.column))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
FunctionElement.column_valued() 方法为上述模式提供了一种快捷方式:
>>> data_view = func.unnest([1, 2, 3]).column_valued("data_view")
>>> print(select(data_view))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
新版本 1.4.0b2 中添加了 .column 访问器
参数:
-
name– 别名,将在 FROM 子句中渲染为AS <name> -
joins_implicitly–当为 True 时,可以在 SQL 查询的 FROM 子句中使用表值函数,而无需显式连接到其他表,并且不会生成“笛卡尔积”警告。 对于
func.json_each()等 SQL 函数可能很有用。新版本 1.4.33 中添加。
另请参阅
表值函数 - 在 SQLAlchemy Unified Tutorial 中
FunctionElement.table_valued()
FunctionElement.scalar_table_valued()
FunctionElement.column_valued()
method as_comparison(left_index: int, right_index: int) → FunctionAsBinary
将此表达式解释为两个值之间的布尔比较。
此方法用于描述 Custom operators based on SQL functions 中的 ORM 用例。
假设的 SQL 函数“is_equal()”,用于比较两个值是否相等,可以用 Core 表达式语言编写为:
expr = func.is_equal("a", "b")
如果上面的“is_equal()”是在比较“a”和“b”是否相等,那么FunctionElement.as_comparison()方法将被调用为:
expr = func.is_equal("a", "b").as_comparison(1, 2)
在上面的例子中,“1”这个整数值是指“is_equal()”函数的第一个参数,“2”这个整数值是指第二个参数。
这将创建一个等效于BinaryExpression的表达式:
BinaryExpression("a", "b", operator=op.eq)
但是,在 SQL 级别上,它仍然会呈现为“is_equal('a','b')”。
当 ORM 加载相关对象或集合时,需要能够操作 JOIN 表达式的 ON 子句的“left”和“right”两边。此方法的目的是在与relationship.primaryjoin参数一起使用时,为 ORM 提供也可以向其提供此信息的 SQL 函数构造。返回值是一个名为FunctionAsBinary的包含对象。
一个 ORM 示例如下:
class Venue(Base):
__tablename__ = 'venue'
id = Column(Integer, primary_key=True)
name = Column(String)
descendants = relationship(
"Venue",
primaryjoin=func.instr(
remote(foreign(name)), name + "/"
).as_comparison(1, 2) == 1,
viewonly=True,
order_by=name
)
上面,“Venue”类可以通过确定父 Venue 的名称是否包含在假设的后代值的名称的开头来加载后代“Venue”对象,例如“parent1”将匹配到“parent1/child1”,但不会匹配到“parent2/child1”。
可能的用例包括上面给出的“材料化路径”示例,以及利用特殊的 SQL 函数(例如几何函数)创建连接条件。
参数:
-
left_index- 作为表达式“left”侧的函数参数的整数基于 1 的索引。 -
right_index- 作为表达式“right”侧的函数参数的整数基于 1 的索引。
版本 1.3 中的新内容。
另请参见
基于 SQL 函数的自定义运算符 - ORM 中的示例用法
attribute c
joins_implicitly - FunctionElement.columns的同义词。
attribute clauses
返回包含此FunctionElement参数的基础ClauseList。
method column_valued(name: str | None = None, joins_implicitly: bool = False) → TableValuedColumn[_T]
将此FunctionElement作为选择自身的 FROM 子句的列表达式返回。
例如:
>>> from sqlalchemy import select, func
>>> gs = func.generate_series(1, 5, -1).column_valued()
>>> print(select(gs))
SELECT anon_1
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) AS anon_1
这是的简写形式:
gs = func.generate_series(1, 5, -1).alias().column
参数:
-
name- 分配给生成的别名的可选名称。如果省略,将使用唯一的匿名名称。 -
joins_implicitly–当为 True 时,列值函数的“表”部分可以成为 SQL 查询中 FROM 子句的成员,而无需对其他表进行显式 JOIN,并且不会生成“笛卡尔积”警告。可能对诸如
func.json_array_elements()等 SQL 函数有用。1.4.46 版本中的新功能。
另请参见
列值函数 - 表值函数作为标量列 - 在 SQLAlchemy 统一教程中
列值函数 - 在 PostgreSQL 文档中
FunctionElement.table_valued()
attribute columns
此FunctionElement导出的一组列。
这是一个占位符集合,允许将函数放置在语句的 FROM 子句中:
>>> from sqlalchemy import column, select, func
>>> stmt = select(column('x'), column('y')).select_from(func.myfunction())
>>> print(stmt)
SELECT x, y FROM myfunction()
上述形式是一个已过时的功能,现在已被完全功能的FunctionElement.table_valued()方法取代;请参阅该方法以获取详情。
另请参见
FunctionElement.table_valued() - 生成表值 SQL 函数表达式。
attribute entity_namespace
覆盖 FromClause.entity_namespace,因为函数通常是列表达式而不是 FromClauses。
attribute exported_columns
method filter(*criterion: _ColumnExpressionArgument[bool]) → Self | FunctionFilter[_T]
针对此函数生成一个 FILTER 子句。
用于针对支持“FILTER”子句的聚合和窗口函数的数据库后端。
表达式:
func.count(1).filter(True)
是的缩写:
from sqlalchemy import funcfilter
funcfilter(func.count(1), True)
另请参见
组内特殊修饰符,过滤器 - 在 SQLAlchemy 统一教程中
FunctionFilter
funcfilter()
method over(*, partition_by: _ByArgument | None = None, order_by: _ByArgument | None = None, rows: Tuple[int | None, int | None] | None = None, range_: Tuple[int | None, int | None] | None = None) → Over[_T]
针对此函数生成一个 OVER 子句。
用于针对聚合或所谓的“窗口”函数,适用于支持窗口函数的数据库后端。
表达式:
func.row_number().over(order_by='x')
是的缩写:
from sqlalchemy import over
over(func.row_number(), order_by='x')
有关完整描述,请参阅over()。
另请参见
over()
使用窗口函数 - 在 SQLAlchemy 统一教程中
method scalar_table_valued(name: str, type_: _TypeEngineArgument[_T] | None = None) → ScalarFunctionColumn[_T]
返回一个列表达式,作为标量表值表达式针对这个FunctionElement。
返回的表达式类似于从FunctionElement.table_valued()结构中访问的单个列返回的表达式,只是不生成 FROM 子句;该函数以类似于标量子查询的方式呈现。
例如:
>>> from sqlalchemy import func, select
>>> fn = func.jsonb_each("{'k', 'v'}").scalar_table_valued("key")
>>> print(select(fn))
SELECT (jsonb_each(:jsonb_each_1)).key
版本 1.4.0b2 中的新功能。
另见
FunctionElement.table_valued()
FunctionElement.alias()
FunctionElement.column_valued()
method select() → Select
产生针对这个FunctionElement的select()构造。
这是的缩写:
s = select(function_element)
method self_group(against: OperatorType | None = None) → ClauseElement
对这个ClauseElement应用一个“分组”。
此方法被子类重写为返回“分组”构造,即括号。特别是,它被“二元”表达式使用,当将它们放入较大的表达式中时,提供对自身的分组,以及当将它们放入另一个select()构造的 FROM 子句中时,被select()构造使用。(请注意,子查询通常应使用Select.alias()方法创建,因为许多平台要求嵌套的 SELECT 语句具有名称)。
随着表达式组合在一起,self_group()的应用是自动的 - 最终用户代码不应直接使用此方法。请注意,SQLAlchemy 的子句构造考虑了运算符优先级 - 因此可能不需要括号,例如,在表达式x OR (y AND z)中可能不需要括号 - AND 优先于 OR。
ClauseElement 的基本方法self_group()只是返回自身。
method table_valued(*expr: _ColumnExpressionOrStrLabelArgument[Any], **kw: Any) → TableValuedAlias
返回一个 FunctionElement 的 TableValuedAlias 表示形式,其中添加了表值表达式。
例如:
>>> fn = (
... func.generate_series(1, 5).
... table_valued("value", "start", "stop", "step")
... )
>>> print(select(fn))
SELECT anon_1.value, anon_1.start, anon_1.stop, anon_1.step
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
>>> print(select(fn.c.value, fn.c.stop).where(fn.c.value > 2))
SELECT anon_1.value, anon_1.stop
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
WHERE anon_1.value > :value_1
通过传递关键字参数“with_ordinality”可以生成一个 WITH ORDINALITY 表达式:
>>> fn = func.generate_series(4, 1, -1).table_valued("gen", with_ordinality="ordinality")
>>> print(select(fn))
SELECT anon_1.gen, anon_1.ordinality
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) WITH ORDINALITY AS anon_1
参数:
-
*expr- 将添加到结果TableValuedAlias构造的.c集合中的一系列字符串列名。也可以使用具有或不具有数据类型的column()对象。 -
name- 分配给生成的别名的可选名称。如果省略,将使用唯一的匿名化名称。 -
with_ordinality- 存在时,将 WITH ORDINALITY 子句添加到别名,并将给定的字符串名称添加为结果TableValuedAlias的.c集合中的列。 -
joins_implicitly-当为 True 时,可以在 SQL 查询的 FROM 子句中使用表值函数,而无需对其他表进行显式的 JOIN,并且不会生成“笛卡尔积”警告。对于 SQL 函数(例如
func.json_each())可能很有用。新版本 1.4.33 中的新增功能。
新版本 1.4.0b2 中的新增功能。
另请参见
表值函数 - 在 SQLAlchemy 统一教程 中
表值函数 - 在 PostgreSQL 文档中
FunctionElement.scalar_table_valued() - FunctionElement.table_valued() 的变体,将完整的表值表达式作为标量列表达式传递
FunctionElement.column_valued()
TableValuedAlias.render_derived() - 使用派生列子句渲染别名,例如 AS name(col1, col2, ...)
method within_group(*order_by: _ColumnExpressionArgument[Any]) → WithinGroup[_T]
生成针对此函数的 WITHIN GROUP (ORDER BY expr) 子句。
用于所谓的“有序集合聚合”和“假设集合聚合”函数,包括 percentile_cont、rank、dense_rank 等。
有关完整描述,请参阅 within_group()。
另请参阅
WITHIN GROUP、FILTER 特殊修饰符 - 在 SQLAlchemy 统一教程 中
method within_group_type(within_group: WithinGroup[_S]) → TypeEngine | None
对于将其返回类型定义为基于 WITHIN GROUP (ORDER BY) 表达式中的条件的类型,由 WithinGroup 构造调用。
默认情况下返回 None,在这种情况下,函数的正常.type被使用。
class sqlalchemy.sql.functions.GenericFunction
定义一个‘通用’函数。
泛型函数是预先定义的 Function 类,在从 func 属性按名称调用时会自动实例化。请注意,从 func 调用任何名称的效果是自动创建一个新的 Function 实例,给定该名称。定义 GenericFunction 类的主要用例是为特定名称的函数指定固定的返回类型。它还可以包括自定义参数解析方案以及其他方法。
GenericFunction 的子类会自动注册到类的名称下。例如,用户定义的函数 as_utc() 将立即可用:
from sqlalchemy.sql.functions import GenericFunction
from sqlalchemy.types import DateTime
class as_utc(GenericFunction):
type = DateTime()
inherit_cache = True
print(select(func.as_utc()))
用户定义的通用函数可以通过在定义 GenericFunction 时指定“package”属性来组织成包。包含许多函数的第三方库可能希望这样做,以避免与其他系统的名称冲突。例如,如果我们的 as_utc() 函数是包 “time” 的一部分:
class as_utc(GenericFunction):
type = DateTime()
package = "time"
inherit_cache = True
上述函数可以通过使用包名 time 从 func 中获得:
print(select(func.time.as_utc()))
最后一种选择是允许从func中的一个名称访问函数,但呈现为不同的名称。identifier属性将覆盖从func加载的函数名称,但将保留name作为呈现名称的用法:
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = "ST_Buffer"
identifier = "buffer"
inherit_cache = True
以上函数将呈现如下:
>>> print(func.geo.buffer())
ST_Buffer()
名称将原样显示,但不会加引号,除非名称包含需要加引号的特殊字符。要在名称上强制加引号或取消引号,请使用quoted_name结构:
from sqlalchemy.sql import quoted_name
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = quoted_name("ST_Buffer", True)
identifier = "buffer"
inherit_cache = True
以上函数将呈现为:
>>> print(func.geo.buffer())
"ST_Buffer"()
可以传递此类作为泛型类型的类的类型参数,并应与Result中看到的类型相匹配。例如:
class as_utc(GenericFunction[datetime.datetime]):
type = DateTime()
inherit_cache = True
以上表明以下表达式返回一个datetime对象:
connection.scalar(select(func.as_utc()))
从版本 1.3.13 开始:在对象的“name”属性中使用quoted_name结构现在被识别为引用,因此可以强制对函数名称进行引用或取消引用。
类签名
类sqlalchemy.sql.functions.GenericFunction(sqlalchemy.sql.functions.Function)
function sqlalchemy.sql.functions.register_function(identifier: str, fn: Type[Function[Any]], package: str = '_default') → None
将可调用对象与特定的函数名关联起来。
通常由 GenericFunction 调用,但也可单独使用,以便将非 Function 构造与func访问器关联起来(即 CAST,EXTRACT)。
选定的“已知”函数
这些是一组常见 SQL 函数的GenericFunction实现,为每个函数自动设置了预期的返回类型。它们以与func命名空间的任何其他成员相同的方式调用:
select(func.count("*")).select_from(some_table)
请注意,任何func未知的名称都会按原样生成函数名称 - SQLAlchemy 对可以调用的 SQL 函数没有限制,不管对 SQLAlchemy 已知还是未知,内置还是用户定义。本节仅描述 SQLAlchemy 已知参数和返回类型的函数。
| 对象名称 | 描述 |
|---|---|
| aggregate_strings | 实现一个通用的字符串聚合函数。 |
| array_agg | 对 ARRAY_AGG 函数的支持。 |
| char_length | CHAR_LENGTH() SQL 函数。 |
| coalesce | |
| concat | SQL CONCAT()函数,用于连接字符串。 |
| count | ANSI COUNT 聚合函数。没有参数时,发出 COUNT *。 |
| cube | 实现CUBE分组操作。 |
| cume_dist | 实现cume_dist假设集合聚合函数。 |
| current_date | CURRENT_DATE() SQL 函数。 |
| current_time | CURRENT_TIME() SQL 函数。 |
| current_timestamp | CURRENT_TIMESTAMP() SQL 函数。 |
| current_user | CURRENT_USER() SQL 函数。 |
| dense_rank | 实现dense_rank假设集合聚合函数。 |
| grouping_sets | 实现GROUPING SETS分组操作。 |
| localtime | localtime() SQL 函数。 |
| localtimestamp | localtimestamp() SQL 函数。 |
| max | SQL MAX()聚合函数。 |
| min | SQL MIN()聚合函数。 |
| mode | 实现mode有序集合聚合函数。 |
| next_value | 代表“下一个值”,给定一个Sequence作为其唯一参数。 |
| now | SQL now()日期时间函数。 |
| percent_rank | 实现percent_rank假设集合聚合函数。 |
| percentile_cont | 实现percentile_cont有序集合聚合函数。 |
| percentile_disc | 实现percentile_disc有序集合聚合函数。 |
| random | RANDOM() SQL 函数。 |
| rank | 实现rank假设集合聚合函数。 |
| rollup | 实现ROLLUP分组操作。 |
| session_user | SESSION_USER() SQL 函数。 |
| sum | SQL SUM()聚合函数。 |
| sysdate | SYSDATE() SQL 函数。 |
| user | USER() SQL 函数。 |
class sqlalchemy.sql.functions.aggregate_strings
实现一个通用的字符串聚合函数。
此函数将非空值连接成字符串,并用分隔符分隔值。
此函数根据每个后端编译为group_concat()、string_agg()或LISTAGG()等函数。
例如,使用分隔符‘.’的示例用法:
stmt = select(func.aggregate_strings(table.c.str_col, "."))
此函数的返回类型是String。
类签名
类sqlalchemy.sql.functions.aggregate_strings(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.array_agg
支持 ARRAY_AGG 函数。
func.array_agg(expr)构造返回类型为ARRAY的表达式。
例如:
stmt = select(func.array_agg(table.c.values)[2:5])
参见
array_agg() - 返回ARRAY的 PostgreSQL 特定版本,其中添加了 PG 特定的运算符。
类签名
类sqlalchemy.sql.functions.array_agg(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.char_length
CHAR_LENGTH() SQL 函数。
类签名
类sqlalchemy.sql.functions.char_length(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.coalesce
类签名
类sqlalchemy.sql.functions.coalesce(sqlalchemy.sql.functions.ReturnTypeFromArgs)
class sqlalchemy.sql.functions.concat
SQL CONCAT()函数,用于连接字符串。
例如:
>>> print(select(func.concat('a', 'b')))
SELECT concat(:concat_2, :concat_3) AS concat_1
在 SQLAlchemy 中,字符串连接更常见地使用 Python 的+运算符与字符串数据类型一起使用,这将呈现特定于后端的连接运算符,例如:
>>> print(select(literal("a") + "b"))
SELECT :param_1 || :param_2 AS anon_1
类签名
类sqlalchemy.sql.functions.concat(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.count
ANSI COUNT 聚合函数。没有参数时,发出 COUNT *。
例如:
from sqlalchemy import func
from sqlalchemy import select
from sqlalchemy import table, column
my_table = table('some_table', column('id'))
stmt = select(func.count()).select_from(my_table)
执行stmt将发出:
SELECT count(*) AS count_1
FROM some_table
类签名
类sqlalchemy.sql.functions.count(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.cube
实现CUBE分组操作。
此函数用作语句的 GROUP BY 的一部分,例如Select.group_by():
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.cube(table.c.col_1, table.c.col_2))
新增于版本 1.2。
类签名
类sqlalchemy.sql.functions.cube(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.cume_dist
实现cume_dist假设集聚合函数。
此函数必须与FunctionElement.within_group()修饰符一起使用,以提供要操作的排序表达式。
此函数的返回类型为Numeric。
类签名
类sqlalchemy.sql.functions.cume_dist(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.current_date
CURRENT_DATE() SQL 函数。
类签名
类sqlalchemy.sql.functions.current_date(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.current_time
CURRENT_TIME() SQL 函数。
类签名
类sqlalchemy.sql.functions.current_time(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.current_timestamp
CURRENT_TIMESTAMP() SQL 函数。
类签名
类sqlalchemy.sql.functions.current_timestamp(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.current_user
CURRENT_USER() SQL 函数。
类签名
类sqlalchemy.sql.functions.current_user(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.dense_rank
实现dense_rank假设集聚合函数。
此函数必须与FunctionElement.within_group()修饰符一起使用,以提供要操作的排序表达式。
此函数的返回类型为Integer。
类签名
类 sqlalchemy.sql.functions.dense_rank(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.grouping_sets
实现 GROUPING SETS 分组操作。
此函数用作语句的 GROUP BY 的一部分,例如 Select.group_by():
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.grouping_sets(table.c.col_1, table.c.col_2))
为了按多个集合进行分组,请使用 tuple_() 构造:
from sqlalchemy import tuple_
stmt = select(
func.sum(table.c.value),
table.c.col_1, table.c.col_2,
table.c.col_3
).group_by(
func.grouping_sets(
tuple_(table.c.col_1, table.c.col_2),
tuple_(table.c.value, table.c.col_3),
)
)
版本 1.2 中的新增内容。
类签名
类 sqlalchemy.sql.functions.grouping_sets(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.localtime
localtime() SQL 函数。
类签名
类 sqlalchemy.sql.functions.localtime(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.localtimestamp
localtimestamp() SQL 函数。
类签名
类 sqlalchemy.sql.functions.localtimestamp(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.max
SQL MAX() 聚合函数。
类签名
类 sqlalchemy.sql.functions.max(sqlalchemy.sql.functions.ReturnTypeFromArgs)
class sqlalchemy.sql.functions.min
SQL MIN() 聚合函数。
类签名
类 sqlalchemy.sql.functions.min(sqlalchemy.sql.functions.ReturnTypeFromArgs)
class sqlalchemy.sql.functions.mode
实现 mode 排序集合聚合函数。
必须与 FunctionElement.within_group() 修改器一起使用,以提供要操作的排序表达式。
此函数的返回类型与排序表达式相同。
类签名
类 sqlalchemy.sql.functions.mode(sqlalchemy.sql.functions.OrderedSetAgg)
class sqlalchemy.sql.functions.next_value
表示“下一个值”,给定 Sequence 作为其唯一参数。
编译为每个后端的适当函数,或者如果在不提供序列支持的后端上使用,则会引发 NotImplementedError。
类签名
类sqlalchemy.sql.functions.next_value(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.now
SQL 的 now()日期时间函数。
SQLAlchemy 方言通常会以特定于后端的方式呈现此特定函数,例如将其呈现为CURRENT_TIMESTAMP。
类签名
类sqlalchemy.sql.functions.now(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.percent_rank
实现percent_rank假设集合聚合函数。
必须使用FunctionElement.within_group()修饰符来提供要操作的排序表达式。
这个函数的返回类型是Numeric。
类签名
类sqlalchemy.sql.functions.percent_rank(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.percentile_cont
实现percentile_cont有序集合聚合函数。
必须使用FunctionElement.within_group()修饰符来提供要操作的排序表达式。
这个函数的返回类型与排序表达式相同,或者如果参数是一个数组,则返回排序表达式类型的ARRAY。
类签名
类sqlalchemy.sql.functions.percentile_cont(sqlalchemy.sql.functions.OrderedSetAgg)
class sqlalchemy.sql.functions.percentile_disc
实现percentile_disc有序集合聚合函数。
必须使用FunctionElement.within_group()修饰符来提供要操作的排序表达式。
这个函数的返回类型与排序表达式相同,或者如果参数是一个数组,则返回排序表达式类型的ARRAY。
类签名
类sqlalchemy.sql.functions.percentile_disc(sqlalchemy.sql.functions.OrderedSetAgg)
class sqlalchemy.sql.functions.random
RANDOM() SQL 函数。
类签名
类sqlalchemy.sql.functions.random (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.rank
实现rank虚拟集合聚合函数。
此函数必须与FunctionElement.within_group()修饰符一起使用,以提供要操作的排序表达式。
此函数的返回类型为Integer。
类签名
类sqlalchemy.sql.functions.rank (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.rollup
实现ROLLUP分组操作。
此函数用作语句的 GROUP BY 的一部分,例如Select.group_by():
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.rollup(table.c.col_1, table.c.col_2))
新版本 1.2 中添加。
类签名
类sqlalchemy.sql.functions.rollup (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.session_user
SESSION_USER() SQL 函数。
类签名
类sqlalchemy.sql.functions.session_user (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.sum
SQL 的 SUM()聚合函数。
类签名
类sqlalchemy.sql.functions.sum (sqlalchemy.sql.functions.ReturnTypeFromArgs)
class sqlalchemy.sql.functions.sysdate
SYSDATE() SQL 函数。
类签名
类sqlalchemy.sql.functions.sysdate (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.user
USER() SQL 函数。
类签名
类sqlalchemy.sql.functions.user (sqlalchemy.sql.functions.AnsiFunction)
函数 API
SQL 函数的基本 API,提供了func命名空间以及可用于可扩展性的类。
| 对象名称 | 描述 |
|---|---|
| AnsiFunction | 定义以“ansi”格式编写的函数,不渲染括号。 |
| Function | 描述一个命名的 SQL 函数。 |
| FunctionElement | 面向 SQL 函数构建的基类。 |
| GenericFunction | 定义一个“通用”函数。 |
| register_function(identifier, fn[, package]) | 将可调用对象与特定的 func. 名称关联起来。 |
class sqlalchemy.sql.functions.AnsiFunction
在“ansi”格式中定义一个不渲染括号的函数。
类签名
类 sqlalchemy.sql.functions.AnsiFunction (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.Function
描述一个命名的 SQL 函数。
Function 对象通常是从 func 生成对象生成的。
参数:
-
*clauses– 形成 SQL 函数调用参数的列表达式列表。 -
type_– 可选的TypeEngine数据类型对象,将用作由此函数调用生成的列表达式的返回值。 -
packagenames–一个字符串,指示在生成 SQL 时要在函数名称之前添加的包前缀名称。当以点格式调用
func生成器时,会创建这些内容,例如:func.mypackage.some_function(col1, col2)
另请参阅
处理 SQL 函数 - 在 SQLAlchemy 统一教程 中
func - 产生注册或临时 Function 实例的命名空间。
GenericFunction - 允许创建已注册的函数类型。
成员
init()
类签名
类 sqlalchemy.sql.functions.Function (sqlalchemy.sql.functions.FunctionElement)
method __init__(name: str, *clauses: _ColumnExpressionOrLiteralArgument[Any], type_: _TypeEngineArgument[_T] | None = None, packagenames: Tuple[str, ...] | None = None)
构建一个 Function。
func 结构通常用于构建新的 Function 实例。
class sqlalchemy.sql.functions.FunctionElement
面向 SQL 函数构建的基类。
这是一个通用类型,意味着类型检查器和集成开发环境可以指示在此函数的 Result 中期望的类型。查看 GenericFunction 以了解如何执行此操作的示例。
另请参阅
使用 SQL 函数 - 在 SQLAlchemy 统一教程 中
Function - 命名的 SQL 函数。
func - 生成注册或临时的 Function 实例的命名空间。
GenericFunction - 允许创建注册的函数类型。
成员
init(), alias(), as_comparison(), c, clauses, column_valued(), columns, entity_namespace, exported_columns, filter(), over(), scalar_table_valued(), select(), self_group(), table_valued(), within_group(), within_group_type()
类签名
类 sqlalchemy.sql.functions.FunctionElement (sqlalchemy.sql.expression.Executable, sqlalchemy.sql.expression.ColumnElement, sqlalchemy.sql.expression.FromClause, sqlalchemy.sql.expression.Generative)
method __init__(*clauses: _ColumnExpressionOrLiteralArgument[Any])
构建一个 FunctionElement。
参数:
-
*clauses– 构成 SQL 函数调用参数的列表达式列表。 -
**kwargs– 通常由子类使用的额外 kwargs。
另请参阅
func
Function
method alias(name: str | None = None, joins_implicitly: bool = False) → TableValuedAlias
根据此 FunctionElement 创建一个 Alias 结构。
提示
FunctionElement.alias() 方法是创建“表值”SQL 函数的机制的一部分。 但是,大多数用例都由 FunctionElement 上的更高级方法覆盖,包括 FunctionElement.table_valued() 和 FunctionElement.column_valued()。
此结构将函数包装在一个适合 FROM 子句的命名别名中,其样式符合 PostgreSQL 示例。 还提供了一个列表达式,使用特殊的 .column 属性,该属性可用于在列或 WHERE 子句中引用函数的输出,例如 PostgreSQL 这样的后端中的标量值。
对于完整的表值表达式,首先使用 FunctionElement.table_valued() 方法来建立具名列。
例如:
>>> from sqlalchemy import func, select, column
>>> data_view = func.unnest([1, 2, 3]).alias("data_view")
>>> print(select(data_view.column))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
FunctionElement.column_valued() 方法提供了上述模式的快捷方式:
>>> data_view = func.unnest([1, 2, 3]).column_valued("data_view")
>>> print(select(data_view))
SELECT data_view
FROM unnest(:unnest_1) AS data_view
新于版本 1.4.0b2:添加了 .column 访问器
参数:
-
name– 别名,将在 FROM 子句中呈现为AS <name> -
joins_implicitly–当为 True 时,可以在 SQL 查询的 FROM 子句中使用表值函数,而无需对其他表进行显式 JOIN,并且不会生成“笛卡尔积”警告。 对于诸如
func.json_each()之类的 SQL 函数可能很有用。新于版本 1.4.33。
另请参阅
表值函数 - 在 SQLAlchemy 统一教程 中
FunctionElement.table_valued()
FunctionElement.scalar_table_valued()
FunctionElement.column_valued()
method as_comparison(left_index: int, right_index: int) → FunctionAsBinary
将此表达式解释为两个值之间的布尔比较。
此方法用于描述 ORM 用例的基于 SQL 函数的自定义运算符。
一个假设的比较两个值是否相等的 SQL 函数“is_equal()”将在 Core 表达式语言中编写为:
expr = func.is_equal("a", "b")
如果上述的“is_equal()”比较的是“a”和“b”的相等性,那么FunctionElement.as_comparison()方法将被调用如下:
expr = func.is_equal("a", "b").as_comparison(1, 2)
在上面,整数值“1”指的是“is_equal()”函数的第一个参数,整数值“2”指的是第二个参数。
这将创建一个等同于的BinaryExpression:
BinaryExpression("a", "b", operator=op.eq)
但是,在 SQL 级别上,它仍然呈现为“is_equal('a', 'b')”。
当 ORM 加载相关对象或集合时,需要能够操作 JOIN 表达式的 ON 子句的“左”和“右”侧。此方法的目的是在使用relationship.primaryjoin参数时,为 ORM 提供一个也可以向其提供此信息的 SQL 函数构造,返回值是一个名为FunctionAsBinary的包含对象。
一个 ORM 示例如下:
class Venue(Base):
__tablename__ = 'venue'
id = Column(Integer, primary_key=True)
name = Column(String)
descendants = relationship(
"Venue",
primaryjoin=func.instr(
remote(foreign(name)), name + "/"
).as_comparison(1, 2) == 1,
viewonly=True,
order_by=name
)
在上面的例子中,“Venue”类可以通过确定父级 Venue 的名称是否包含在假想后代值的名称的开头来加载后代“Venue”对象,例如,“parent1”将匹配到“parent1/child1”,但不会匹配到“parent2/child1”。
可能的用例包括上面给出的“materialized path”示例,以及利用特殊的 SQL 函数来创建连接条件,如几何函数。
参数:
-
left_index– 函数参数中作为“左侧”表达式的整数索引(从 1 开始)。 -
right_index– 函数参数中作为“右侧”表达式的整数索引(从 1 开始)。
版本 1.3 中的新功能。
另请参阅
基于 SQL 函数的自定义运算符 - 在 ORM 中的示例用法
attribute c
FunctionElement.columns的同义词。
attribute clauses
返回包含此FunctionElement参数的ClauseList的基础对象。
method column_valued(name: str | None = None, joins_implicitly: bool = False) → TableValuedColumn[_T]
将此FunctionElement作为从自身选择的列表达式返回。
例如:
>>> from sqlalchemy import select, func
>>> gs = func.generate_series(1, 5, -1).column_valued()
>>> print(select(gs))
SELECT anon_1
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) AS anon_1
这是的简写形式:
gs = func.generate_series(1, 5, -1).alias().column
参数:
-
name- 可选的名称,用于分配生成的别名名称。如果省略,将使用唯一的匿名名称。 -
joins_implicitly-当为 True 时,列值函数的“table”部分可以作为 SQL 查询中 FROM 子句的成员,而不需要对其他表进行显式 JOIN,并且不会生成“笛卡尔积”警告。 对于诸如
func.json_array_elements()之类的 SQL 函数可能有用。1.4.46 版中的新功能。
请参阅
列值函数 - 表值函数作为标量列 - 在 SQLAlchemy 统一教程中
列值函数 - 在 PostgreSQL 文档中
FunctionElement.table_valued()
attribute columns
此FunctionElement导出的列的集合。
这是一个占位符集合,允许将函数放置在语句的 FROM 子句中:
>>> from sqlalchemy import column, select, func
>>> stmt = select(column('x'), column('y')).select_from(func.myfunction())
>>> print(stmt)
SELECT x, y FROM myfunction()
上述形式是一个现在已被完全功能的FunctionElement.table_valued()方法所取代的遗留特性;有关详细信息,请参阅该方法。
请参阅
FunctionElement.table_valued() - 生成表值 SQL 函数表达式。
attribute entity_namespace
覆盖 FromClause.entity_namespace,因为函数通常是列表达式,而不是 FromClauses。
attribute exported_columns
method filter(*criterion: _ColumnExpressionArgument[bool]) → Self | FunctionFilter[_T]
产生针对此函数的 FILTER 子句。
用于支持“FILTER”子句的数据库后端中的聚合和窗口函数。
表达式:
func.count(1).filter(True)
是的简写形式:
from sqlalchemy import funcfilter
funcfilter(func.count(1), True)
请参阅
特殊修饰符 WITHIN GROUP,FILTER - 在 SQLAlchemy 统一教程中
FunctionFilter
funcfilter()
method over(*, partition_by: _ByArgument | None = None, order_by: _ByArgument | None = None, rows: Tuple[int | None, int | None] | None = None, range_: Tuple[int | None, int | None] | None = None) → Over[_T]
产生针对此函数的 OVER 子句。
用于支持窗口函数的聚合或所谓的“窗口”函数的数据库后端。
表达式:
func.row_number().over(order_by='x')
是的简写形式:
from sqlalchemy import over
over(func.row_number(), order_by='x')
请参阅over()以获取完整描述。
请参阅
over()
使用窗口函数 - 在 SQLAlchemy 统一教程中
method scalar_table_valued(name: str, type_: _TypeEngineArgument[_T] | None = None) → ScalarFunctionColumn[_T]
返回一个针对这个FunctionElement的列表达式作为标量表值表达式。
返回的表达式类似于从FunctionElement.table_valued()构造中访问的单个列返回的表达式,除了不生成 FROM 子句;该函数以标量子查询的方式呈现。
例如:
>>> from sqlalchemy import func, select
>>> fn = func.jsonb_each("{'k', 'v'}").scalar_table_valued("key")
>>> print(select(fn))
SELECT (jsonb_each(:jsonb_each_1)).key
版本 1.4.0b2 中的新功能。
另请参见
FunctionElement.table_valued()
FunctionElement.alias()
FunctionElement.column_valued()
method select() → Select
产生一个针对这个FunctionElement的select()构造。
这是一个简写:
s = select(function_element)
method self_group(against: OperatorType | None = None) → ClauseElement
对这个ClauseElement应用一个“分组”。
子类重写此方法以返回一个“分组”构造,即括号。特别是它被“二元”表达式使用,当它们被放置到更大的表达式中时提供一个围绕自身的分组,以及当它们被放置到另一个select()的 FROM 子句中时,由select()构造使用。(请注意,子查询通常应该使用Select.alias()方法创建,因为许多平台要求嵌套的 SELECT 语句必须被命名)。
随着表达式的组合,self_group() 的应用是自动的 - 最终用户代码不应该直接使用这个方法。请注意,SQLAlchemy 的子句构造考虑了运算符优先级 - 因此在表达式中可能不需要括号,例如,x OR (y AND z) - AND 优先于 OR。
ClauseElement的基本self_group()方法只返回自身。
method table_valued(*expr: _ColumnExpressionOrStrLabelArgument[Any], **kw: Any) → TableValuedAlias
返回此FunctionElement的TableValuedAlias表示,其中添加了表值表达式。
例如:
>>> fn = (
... func.generate_series(1, 5).
... table_valued("value", "start", "stop", "step")
... )
>>> print(select(fn))
SELECT anon_1.value, anon_1.start, anon_1.stop, anon_1.step
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
>>> print(select(fn.c.value, fn.c.stop).where(fn.c.value > 2))
SELECT anon_1.value, anon_1.stop
FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
WHERE anon_1.value > :value_1
通过传递关键字参数“with_ordinality”可以生成一个 WITH ORDINALITY 表达式:
>>> fn = func.generate_series(4, 1, -1).table_valued("gen", with_ordinality="ordinality")
>>> print(select(fn))
SELECT anon_1.gen, anon_1.ordinality
FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) WITH ORDINALITY AS anon_1
参数:
-
*expr– 一系列将作为列添加到结果的TableValuedAlias构造中的字符串列名。也可以使用具有或不具有数据类型的column()对象。 -
name– 分配给生成的别名名称的可选名称。如果省略,将使用唯一的匿名化名称。 -
with_ordinality– 当存在时,会将WITH ORDINALITY子句添加到别名中,并且给定的字符串名称将作为列添加到结果的TableValuedAlias的.c集合中。 -
joins_implicitly–当为 True 时,可以在 SQL 查询的 FROM 子句中使用表值函数,而无需对其他表进行显式 JOIN,并且不会生成“笛卡尔积”警告。对于诸如
func.json_each()之类的 SQL 函数可能很有用。新功能在版本 1.4.33 中引入。
新功能在版本 1.4.0b2 中引入。
另请参阅
表值函数 - 在 SQLAlchemy 统一教程中
表值函数 - 在 PostgreSQL 文档中
FunctionElement.scalar_table_valued() - FunctionElement.table_valued()的变体,将完整的表值表达式作为标量列表达式传递
FunctionElement.column_valued()
TableValuedAlias.render_derived() - 使用派生列子句呈现别名,例如AS name(col1, col2, ...)
method within_group(*order_by: _ColumnExpressionArgument[Any]) → WithinGroup[_T]
生成一个针对此函数的 WITHIN GROUP (ORDER BY expr) 子句。
用于所谓的“有序集合聚合”和“假设集合聚合”函数,包括percentile_cont、rank、dense_rank等。
详细描述请参见within_group()。
另请参见
WITHIN GROUP、FILTER 特殊修饰符 - 在 SQLAlchemy 统一教程中
method within_group_type(within_group: WithinGroup[_S]) → TypeEngine | None
对于将其返回类型定义为基于 WITHIN GROUP (ORDER BY) 表达式中的条件的类型,通过 WithinGroup 构造调用。
默认情况下返回 None,此时使用函数的普通.type。
class sqlalchemy.sql.functions.GenericFunction
定义一个“通用”函数。
通用函数是预先建立的Function类,在从func属性中按名称调用时自动实例化。请注意,从func调用任何名称都会自动创建一个新的Function实例,给定该名称。定义GenericFunction类的主要用例是为特定名称的函数指定固定的返回类型。它还可以包括自定义参数解析方案以及其他方法。
GenericFunction的子类会自动注册在类的名称下。例如,用户定义的函数as_utc()将立即可用:
from sqlalchemy.sql.functions import GenericFunction
from sqlalchemy.types import DateTime
class as_utc(GenericFunction):
type = DateTime()
inherit_cache = True
print(select(func.as_utc()))
用户定义的通用函数可以通过在定义GenericFunction时指定“package”属性来组织到包中。许多函数的第三方库可能想要使用此功能,以避免与其他系统的名称冲突。例如,如果我们的 as_utc() 函数是“time”包的一部分:
class as_utc(GenericFunction):
type = DateTime()
package = "time"
inherit_cache = True
上述函数可以通过func来使用,使用包名time:
print(select(func.time.as_utc()))
最后一个选项是允许从func中的一个名称访问该函数,但呈现为不同的名称。 identifier 属性将覆盖从func加载时用于访问函数的名称,但将保留使用 name 作为呈现名称的用法:
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = "ST_Buffer"
identifier = "buffer"
inherit_cache = True
上述函数将呈现如下:
>>> print(func.geo.buffer())
ST_Buffer()
名称将按原样呈现,但如果名称包含需要引用的特殊字符,则不会引用。要强制对名称进行引用或取消引用,请使用 quoted_name 结构:
from sqlalchemy.sql import quoted_name
class GeoBuffer(GenericFunction):
type = Geometry()
package = "geo"
name = quoted_name("ST_Buffer", True)
identifier = "buffer"
inherit_cache = True
上述函数将呈现为:
>>> print(func.geo.buffer())
"ST_Buffer"()
此类的类型参数作为 通用类型 可以传递,并且应该与 Result 中看到的类型匹配。例如:
class as_utc(GenericFunction[datetime.datetime]):
type = DateTime()
inherit_cache = True
以上表明以下表达式返回一个 datetime 对象:
connection.scalar(select(func.as_utc()))
从版本 1.3.13 开始:当与对象的“name”属性一起使用时,quoted_name 结构现在被识别为引用,因此可以强制对函数名称进行引用。
类签名
类sqlalchemy.sql.functions.GenericFunction (sqlalchemy.sql.functions.Function)
function sqlalchemy.sql.functions.register_function(identifier: str, fn: Type[Function[Any]], package: str = '_default') → None
将可调用对象与特定的函数名称关联起来。
通常由 GenericFunction 调用,但也可以单独使用,以便将非 Function 结构与func访问器关联起来(例如 CAST、EXTRACT)。
选定的“已知”函数
这些是一组选定的常见 SQL 函数的GenericFunction实现,为每个函数自动设置了预期的返回类型。它们以与func命名空间的任何其他成员相同的方式调用:
select(func.count("*")).select_from(some_table)
请注意,任何未知于func的名称都会按原样生成函数名称 - 对于可以调用的 SQL 函数,对 SQLAlchemy 有无所谓是否知道它们,内置或用户定义的没有限制。这里的部分仅描述了 SQLAlchemy 已经知道正在使用什么参数和返回类型的函数。
| 对象名称 | 描述 |
|---|---|
| aggregate_strings | 实现一个通用的字符串聚合函数。 |
| array_agg | 支持 ARRAY_AGG 函数。 |
| char_length | CHAR_LENGTH() SQL 函数。 |
| coalesce | |
| concat | SQL CONCAT() 函数,用于连接字符串。 |
| count | ANSI COUNT 聚合函数。没有参数时,发出 COUNT *。 |
| cube | 实现CUBE分组操作。 |
| cume_dist | 实现cume_dist假设集聚合函数。 |
| current_date | CURRENT_DATE() SQL 函数。 |
| current_time | CURRENT_TIME() SQL 函数。 |
| current_timestamp | CURRENT_TIMESTAMP() SQL 函数。 |
| current_user | CURRENT_USER() SQL 函数。 |
| dense_rank | 实现dense_rank假设集聚合函数。 |
| grouping_sets | 实现GROUPING SETS分组操作。 |
| localtime | localtime() SQL 函数。 |
| localtimestamp | localtimestamp() SQL 函数。 |
| max | SQL MAX() 聚合函数。 |
| min | SQL MIN() 聚合函数。 |
| mode | 实现mode有序集聚合函数。 |
| next_value | 代表“下一个值”,以Sequence作为其唯一参数。 |
| now | SQL now() 日期时间函数。 |
| percent_rank | 实现percent_rank假设集聚合函数。 |
| percentile_cont | 实现percentile_cont有序集聚合函数。 |
| percentile_disc | 实现percentile_disc有序集聚合函数。 |
| random | RANDOM() SQL 函数。 |
| rank | 实现rank假设集聚合函数。 |
| rollup | 实现ROLLUP分组操作。 |
| session_user | SESSION_USER() SQL 函数。 |
| sum | SQL SUM() 聚合函数。 |
| sysdate | SYSDATE() SQL 函数。 |
| user | USER() SQL 函数。 |
class sqlalchemy.sql.functions.aggregate_strings
实现一个通用的字符串聚合函数。
此函数将非空值连接为一个字符串,并用分隔符分隔值。
此函数根据每个后端编译为group_concat()、string_agg()或LISTAGG()等函数。
例如,使用分隔符‘.’的示例用法:
stmt = select(func.aggregate_strings(table.c.str_col, "."))
此函数的返回类型为String。
类签名
类sqlalchemy.sql.functions.aggregate_strings(sqlalchemy.sql.functions.GenericFunction)。
class sqlalchemy.sql.functions.array_agg
支持 ARRAY_AGG 函数。
func.array_agg(expr)构造返回类型为ARRAY的表达式。
例如:
stmt = select(func.array_agg(table.c.values)[2:5])
另请参阅
array_agg() - 返回ARRAY的 PostgreSQL 特定版本,其中添加了 PG 特定运算符。
类签名
类sqlalchemy.sql.functions.array_agg(sqlalchemy.sql.functions.GenericFunction)。
class sqlalchemy.sql.functions.char_length
SQL 函数CHAR_LENGTH().
类签名
类sqlalchemy.sql.functions.char_length(sqlalchemy.sql.functions.GenericFunction)。
class sqlalchemy.sql.functions.coalesce
类签名
类sqlalchemy.sql.functions.coalesce(sqlalchemy.sql.functions.ReturnTypeFromArgs)。
class sqlalchemy.sql.functions.concat
SQL CONCAT()函数,用于连接字符串。
例如:
>>> print(select(func.concat('a', 'b')))
SELECT concat(:concat_2, :concat_3) AS concat_1
在 SQLAlchemy 中,使用 Python 的+运算符与字符串数据类型更常见,这将呈现特定于后端的连接运算符,例如:
>>> print(select(literal("a") + "b"))
SELECT :param_1 || :param_2 AS anon_1
类签名
类sqlalchemy.sql.functions.concat(sqlalchemy.sql.functions.GenericFunction)。
class sqlalchemy.sql.functions.count
ANSI COUNT 聚合函数。没有参数时,发出 COUNT *。
例如:
from sqlalchemy import func
from sqlalchemy import select
from sqlalchemy import table, column
my_table = table('some_table', column('id'))
stmt = select(func.count()).select_from(my_table)
执行stmt将发出:
SELECT count(*) AS count_1
FROM some_table
类签名
类sqlalchemy.sql.functions.count(sqlalchemy.sql.functions.GenericFunction)。
class sqlalchemy.sql.functions.cube
实现CUBE分组操作。
此函数用作语句的 GROUP BY 的一部分,例如 Select.group_by():
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.cube(table.c.col_1, table.c.col_2))
新版本 1.2 中新增。
类签名
class sqlalchemy.sql.functions.cube (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.cume_dist
实现 cume_dist 假设集聚合函数。
必须使用 FunctionElement.within_group() 修饰符来提供一个排序表达式以进行操作。
该函数的返回类型是 Numeric。
类签名
class sqlalchemy.sql.functions.cume_dist (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.current_date
CURRENT_DATE() SQL 函数。
类签名
class sqlalchemy.sql.functions.current_date (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.current_time
CURRENT_TIME() SQL 函数。
类签名
class sqlalchemy.sql.functions.current_time (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.current_timestamp
CURRENT_TIMESTAMP() SQL 函数。
类签名
class sqlalchemy.sql.functions.current_timestamp (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.current_user
CURRENT_USER() SQL 函数。
类签名
class sqlalchemy.sql.functions.current_user (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.dense_rank
实现 dense_rank 假设集聚合函数。
必须使用 FunctionElement.within_group() 修饰符来提供一个排序表达式以进行操作。
该函数的返回类型是 Integer。
类签名
类sqlalchemy.sql.functions.dense_rank(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.grouping_sets
实现 GROUPING SETS 分组操作。
此函数用作语句的 GROUP BY 的一部分,例如 Select.group_by():
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.grouping_sets(table.c.col_1, table.c.col_2))
要按多个集合分组,请使用tuple_()结构:
from sqlalchemy import tuple_
stmt = select(
func.sum(table.c.value),
table.c.col_1, table.c.col_2,
table.c.col_3
).group_by(
func.grouping_sets(
tuple_(table.c.col_1, table.c.col_2),
tuple_(table.c.value, table.c.col_3),
)
)
版本 1.2 中的新功能。
类签名
类sqlalchemy.sql.functions.grouping_sets(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.localtime
localtime() SQL 函数。
类签名
类sqlalchemy.sql.functions.localtime(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.localtimestamp
localtimestamp() SQL 函数。
类签名
类sqlalchemy.sql.functions.localtimestamp(sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.max
SQL MAX() 聚合函数。
类签名
类sqlalchemy.sql.functions.max(sqlalchemy.sql.functions.ReturnTypeFromArgs)
class sqlalchemy.sql.functions.min
SQL MIN() 聚合函数。
类签名
类sqlalchemy.sql.functions.min(sqlalchemy.sql.functions.ReturnTypeFromArgs)
class sqlalchemy.sql.functions.mode
实现 mode 有序集合聚合函数。
这个函数必须与FunctionElement.within_group()修饰符一起使用,以提供要操作的排序表达式。
此函数的返回类型与排序表达式相同。
类签名
类sqlalchemy.sql.functions.mode(sqlalchemy.sql.functions.OrderedSetAgg)
class sqlalchemy.sql.functions.next_value
代表给定Sequence作为其唯一参数的‘下一个值’。
在每个后端编译成适当的函数,或者如果在不提供序列支持的后端上使用则会引发 NotImplementedError。
类签名
类sqlalchemy.sql.functions.next_value(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.now
SQL 现在()日期时间函数。
SQLAlchemy 方言通常以特定于后端的方式呈现此特定函数,例如将其呈现为CURRENT_TIMESTAMP。
类签名
类sqlalchemy.sql.functions.now(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.percent_rank
实现percent_rank假设集合聚合函数。
必须使用FunctionElement.within_group()修饰符来提供要操作的排序表达式。
此函数的返回类型是Numeric。
类签名
类sqlalchemy.sql.functions.percent_rank(sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.percentile_cont
实现percentile_cont有序集合聚合函数。
必须使用FunctionElement.within_group()修饰符来提供要操作的排序表达式。
此函数的返回类型与排序表达式相同,或者如果参数是数组,则为排序表达式类型的ARRAY。
类签名
类sqlalchemy.sql.functions.percentile_cont(sqlalchemy.sql.functions.OrderedSetAgg)
class sqlalchemy.sql.functions.percentile_disc
实现percentile_disc有序集合聚合函数。
必须使用FunctionElement.within_group()修饰符来提供要操作的排序表达式。
此函数的返回类型与排序表达式相同,或者如果参数是数组,则为排序表达式类型的ARRAY。
类签名
类sqlalchemy.sql.functions.percentile_disc(sqlalchemy.sql.functions.OrderedSetAgg)
class sqlalchemy.sql.functions.random
RANDOM() SQL 函数。
类签名
类 sqlalchemy.sql.functions.random (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.rank
实现 rank 虚拟集合聚合函数。
此函数必须与 FunctionElement.within_group() 修改器一起使用,以提供要操作的排序表达式。
此函数的返回类型是 Integer。
类签名
类 sqlalchemy.sql.functions.rank (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.rollup
实现 ROLLUP 分组操作。
此函数用作语句的 GROUP BY 的一部分,例如 Select.group_by():
stmt = select(
func.sum(table.c.value), table.c.col_1, table.c.col_2
).group_by(func.rollup(table.c.col_1, table.c.col_2))
新版本 1.2 中添加。
类签名
类 sqlalchemy.sql.functions.rollup (sqlalchemy.sql.functions.GenericFunction)
class sqlalchemy.sql.functions.session_user
SESSION_USER() SQL 函数。
类签名
类 sqlalchemy.sql.functions.session_user (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.sum
SQL SUM() 聚合函数。
类签名
类 sqlalchemy.sql.functions.sum (sqlalchemy.sql.functions.ReturnTypeFromArgs)
class sqlalchemy.sql.functions.sysdate
SYSDATE() SQL 函数。
类签名
类 sqlalchemy.sql.functions.sysdate (sqlalchemy.sql.functions.AnsiFunction)
class sqlalchemy.sql.functions.user
USER() SQL 函数。
类签名
类 sqlalchemy.sql.functions.user (sqlalchemy.sql.functions.AnsiFunction)
自定义 SQL 构造和编译扩展
提供了用于创建自定义 ClauseElements 和编译器的 API。
概要
使用涉及创建一个或多个ClauseElement子类和一个或多个定义其编译的可调用对象:
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import ColumnClause
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
在上面,MyColumn扩展了ColumnClause,这是命名列对象的基本表达式元素。compiles装饰器向MyColumn类注册自身,以便在将对象编译为字符串时调用它:
from sqlalchemy import select
s = select(MyColumn('x'), MyColumn('y'))
print(str(s))
产生:
SELECT [x], [y]
方言特定的编译规则
编译器也可以是特定于方言的。将为使用的方言调用适当的编译器:
from sqlalchemy.schema import DDLElement
class AlterColumn(DDLElement):
inherit_cache = False
def __init__(self, column, cmd):
self.column = column
self.cmd = cmd
@compiles(AlterColumn)
def visit_alter_column(element, compiler, **kw):
return "ALTER COLUMN %s ..." % element.column.name
@compiles(AlterColumn, 'postgresql')
def visit_alter_column(element, compiler, **kw):
return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name,
element.column.name)
当使用任何postgresql方言时,第二个visit_alter_table将被调用。
编译自定义表达式构造的子元素
compiler参数是正在使用的Compiled对象。可以检查此对象的任何有关进行中编译的信息,包括compiler.dialect、compiler.statement等。SQLCompiler和DDLCompiler都包括一个process()方法,可用于编译嵌入属性:
from sqlalchemy.sql.expression import Executable, ClauseElement
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
insert = InsertFromSelect(t1, select(t1).where(t1.c.x>5))
print(insert)
产生:
"INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z
FROM mytable WHERE mytable.x > :x_1)"
注意
上述的InsertFromSelect构造仅是一个示例,这种实际功能已经可以使用Insert.from_select()方法。
在 SQL 和 DDL 编译器之间进行交叉编译
SQL 和 DDL 构造分别使用不同的基本编译器 - SQLCompiler和DDLCompiler。一个常见的需求是从 DDL 表达式中访问 SQL 表达式的编译规则。DDLCompiler包含一个访问器sql_compiler,因此我们可以生成嵌入 SQL 表达式的 CHECK 约束,如下所示:
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
kw['literal_binds'] = True
return "CONSTRAINT %s CHECK (%s)" % (
constraint.name,
ddlcompiler.sql_compiler.process(
constraint.expression, **kw)
)
在上面,我们在SQLCompiler.process()中调用的过程步骤中添加了一个额外的标志,即literal_binds标志。这表示任何引用BindParameter对象或其他“literal”对象(如引用字符串或整数的对象)的 SQL 表达式应该原地呈现,而不是作为绑定参数引用;在发出 DDL 时,通常不支持绑定参数。
更改现有构造的默认编译
编译器扩展同样适用于现有的结构。当覆盖内置 SQL 结构的编译时,@compiles 装饰器会调用适当的类(确保使用类,即 Insert 或 Select,而不是创建函数,比如 insert() 或 select())。
在新的编译函数中,要获取“原始”的编译例程,使用适当的 visit_XXX 方法 - 这是因为编译器.process() 将调用重写的例程并导致无限循环。比如,要向所有的插入语句添加“前缀”:
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def prefix_inserts(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with("some prefix"), **kw)
上述编译器在编译时会在所有的 INSERT 语句前加上“某个前缀”。
更改类型的编译
compiler 也适用于类型,比如下面我们为 String/VARCHAR 实现了 MS-SQL 特定的 ‘max’ 关键字:
@compiles(String, 'mssql')
@compiles(VARCHAR, 'mssql')
def compile_varchar(element, compiler, **kw):
if element.length == 'max':
return "VARCHAR('max')"
else:
return compiler.visit_VARCHAR(element, **kw)
foo = Table('foo', metadata,
Column('data', VARCHAR('max'))
)
子类化指南
使用编译器扩展的一个重要部分是子类化 SQLAlchemy 表达式结构。为了使这更容易,表达式和模式包含一组旨在用于常见任务的“基础”。概要如下:
-
ClauseElement- 这是根表达式类。任何 SQL 表达式都可以从这个基类派生,并且对于长一些的构造,比如专门的 INSERT 语句,这可能是最好的选择。 -
ColumnElement- 所有“类似列”的元素的根。你在 SELECT 语句的“列”子句中(以及 order by 和 group by)放置的任何东西都可以从这个派生 - 该对象将自动具有 Python 的“比较”行为。ColumnElement类希望有一个type成员,该成员是表达式的返回类型。这可以在构造函数的实例级别或类级别上建立:class timestamp(ColumnElement): type = TIMESTAMP() inherit_cache = True -
FunctionElement- 这是ColumnElement和“from 子句”类似对象的混合体,并表示 SQL 函数或存储过程类型的调用。由于大多数数据库支持“SELECT FROM <某个函数>”这样的语句,FunctionElement添加了在select()构造的 FROM 子句中使用的能力:from sqlalchemy.sql.expression import FunctionElement class coalesce(FunctionElement): name = 'coalesce' inherit_cache = True @compiles(coalesce) def compile(element, compiler, **kw): return "coalesce(%s)" % compiler.process(element.clauses, **kw) @compiles(coalesce, 'oracle') def compile(element, compiler, **kw): if len(element.clauses) > 2: raise TypeError("coalesce only supports two arguments on Oracle") return "nvl(%s)" % compiler.process(element.clauses, **kw) -
ExecutableDDLElement- 所有 DDL 表达式的根,比如 CREATE TABLE,ALTER TABLE 等。ExecutableDDLElement的子类的编译由DDLCompiler发出,而不是由SQLCompiler发出。ExecutableDDLElement也可以与DDLEvents.before_create()和DDLEvents.after_create()等事件钩子一起用作事件钩子,允许在 CREATE TABLE 和 DROP TABLE 序列期间自动调用构造。另请参见
自定义 DDL - 包含将
DDL对象(它们本身是ExecutableDDLElement实例)与DDLEvents事件钩子相关联的示例。 -
Executable- 这是一个 mixin,应该与任何表示可以直接传递给execute()方法的“独立”SQL 语句的表达式类一起使用。它已经隐含在DDLElement和FunctionElement中。
上述大部分构造也响应 SQL 语句缓存。子类构造将希望为对象定义缓存行为,这通常意味着将标志inherit_cache设置为False或True的值。有关背景信息,请参见下一节为自定义构造启用缓存支持。
为自定义构造启用缓存支持
从版本 1.4 开始,SQLAlchemy 包括一个 SQL 编译缓存设施,它将允许等效的 SQL 构造缓存它们的字符串形式,以及用于从语句中获取结果的其他结构信息。
如在对象不会生成缓存键,性能影响中讨论的原因,该缓存系统的实现对于在缓存系统中包含自定义 SQL 构造和/或子类采取了保守的方法。这包括任何用户定义的 SQL 构造,包括此扩展的所有示例,除非它们明确声明能够这样做,否则默认情况下不会参与缓存。当在特定子类的类级别设置HasCacheKey.inherit_cache属性为True时,将指示该类的实例可以安全地进行缓存,使用直接父类的缓存键生成方案。例如,这适用于先前指示的“概要”示例:
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
上面,MyColumn类不包含任何影响其 SQL 编译的新状态;MyColumn实例的缓存键将利用ColumnClause超类的缓存键,这意味着它将考虑对象的类(MyColumn)、对象的字符串名称和数据类型:
>>> MyColumn("some_name", String())._generate_cache_key()
CacheKey(
key=('0', <class '__main__.MyColumn'>,
'name', 'some_name',
'type', (<class 'sqlalchemy.sql.sqltypes.String'>,
('length', None), ('collation', None))
), bindparams=[])
对于那些在许多更大语句中可能被大量使用作为组件的对象,比如Column子类和自定义 SQL 数据类型,尽可能启用缓存非常重要,否则可能会对性能产生负面影响。
一个包含影响其 SQL 编译的状态的对象示例是在编译自定义表达式构造的子元素中所示的一个示例;这是一个将Table和Select构造组合在一起的“INSERT FROM SELECT”构造,每个构造独立影响构造的 SQL 字符串生成。对于这个类,示例说明它根本不参与缓存:
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
虽然上述InsertFromSelect也可能生成由Table和Select组件组合而成的缓存键,但目前该 API 并不完全公开。然而,对于“INSERT FROM SELECT”构造,它仅用于特定操作,缓存并不像前面的示例那样关键。
对于在相对孤立并且通常是独立的对象,例如自定义 DML 构造,如 “INSERT FROM SELECT”,缓存通常不那么关键,因为对于这种构造缺乏缓存仅对该特定操作具有局部影响。
更多示例
“UTC 时间戳”函数
一个类似于 “CURRENT_TIMESTAMP” 的函数,但应用适当的转换,使时间为 UTC 时间。时间戳最好存储在关系型数据库中作为 UTC,不带时区。UTC 使您的数据库在夏令时结束时不会认为时间已经倒退,不带时区是因为时区就像字符编码 - 最好只在应用程序的端点(即在用户输入时转换为 UTC,在显示时重新应用所需的时区)应用它们。
对于 PostgreSQL 和 Microsoft SQL Server:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
class utcnow(expression.FunctionElement):
type = DateTime()
inherit_cache = True
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
@compiles(utcnow, 'mssql')
def ms_utcnow(element, compiler, **kw):
return "GETUTCDATE()"
示例用法:
from sqlalchemy import (
Table, Column, Integer, String, DateTime, MetaData
)
metadata = MetaData()
event = Table("event", metadata,
Column("id", Integer, primary_key=True),
Column("description", String(50), nullable=False),
Column("timestamp", DateTime, server_default=utcnow())
)
“GREATEST”函数
“GREATEST”函数接受任意数量的参数,并返回具有最高值的参数 - 它等同于 Python 的 max 函数。与仅容纳两个参数的基于 CASE 的版本相比,SQL 标准版本:
from sqlalchemy.sql import expression, case
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import Numeric
class greatest(expression.FunctionElement):
type = Numeric()
name = 'greatest'
inherit_cache = True
@compiles(greatest)
def default_greatest(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(greatest, 'sqlite')
@compiles(greatest, 'mssql')
@compiles(greatest, 'oracle')
def case_greatest(element, compiler, **kw):
arg1, arg2 = list(element.clauses)
return compiler.process(case((arg1 > arg2, arg1), else_=arg2), **kw)
示例用法:
Session.query(Account).\
filter(
greatest(
Account.checking_balance,
Account.savings_balance) > 10000
)
“false” 表达式
渲染“false”常量表达式,对于没有“false”常量的平台,渲染为“0”:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
class sql_false(expression.ColumnElement):
inherit_cache = True
@compiles(sql_false)
def default_false(element, compiler, **kw):
return "false"
@compiles(sql_false, 'mssql')
@compiles(sql_false, 'mysql')
@compiles(sql_false, 'oracle')
def int_false(element, compiler, **kw):
return "0"
示例用法:
from sqlalchemy import select, union_all
exp = union_all(
select(users.c.name, sql_false().label("enrolled")),
select(customers.c.name, customers.c.enrolled)
)
| 对象名称 | 描述 |
|---|---|
| compiles(class_, *specs) | 为给定ClauseElement类型注册函数作为编译器。 |
| deregister(class_) | 删除与给定ClauseElement类型关联的所有自定义编译器。 |
function sqlalchemy.ext.compiler.compiles(class_, *specs)
为给定ClauseElement类型注册函数作为编译器。
function sqlalchemy.ext.compiler.deregister(class_)
删除与给定ClauseElement类型关联的所有自定义编译器。
概要
使用涉及创建一个或多个ClauseElement子类和一个或多个定义其编译的可调用对象:
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import ColumnClause
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
上面,MyColumn 扩展了ColumnClause,命名列对象的基本表达式元素。compiles 装饰器将自身注册到 MyColumn 类,以便在对象编译为字符串时调用它:
from sqlalchemy import select
s = select(MyColumn('x'), MyColumn('y'))
print(str(s))
产生:
SELECT [x], [y]
特定于方言的编译规则
编译器也可以是特定于方言的。将为使用的方言调用适当的编译器:
from sqlalchemy.schema import DDLElement
class AlterColumn(DDLElement):
inherit_cache = False
def __init__(self, column, cmd):
self.column = column
self.cmd = cmd
@compiles(AlterColumn)
def visit_alter_column(element, compiler, **kw):
return "ALTER COLUMN %s ..." % element.column.name
@compiles(AlterColumn, 'postgresql')
def visit_alter_column(element, compiler, **kw):
return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name,
element.column.name)
当使用任何 postgresql 方言时,将调用第二个 visit_alter_table。
编译自定义表达式结构的子元素
compiler 参数是正在使用的 Compiled 对象。此对象可以用于检查关于正在进行的编译的任何信息,包括 compiler.dialect、compiler.statement 等。SQLCompiler 和 DDLCompiler 都包含一个 process() 方法,可用于编译嵌入属性:
from sqlalchemy.sql.expression import Executable, ClauseElement
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
insert = InsertFromSelect(t1, select(t1).where(t1.c.x>5))
print(insert)
产生:
"INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z
FROM mytable WHERE mytable.x > :x_1)"
注意
上述的 InsertFromSelect 构造只是一个例子,实际功能已经可以使用 Insert.from_select() 方法实现。
在 SQL 和 DDL 编译器之间进行交叉编译
SQL 和 DDL 构造使用不同的基础编译器 - SQLCompiler 和 DDLCompiler 进行编译。常见的需要是从 DDL 表达式中访问 SQL 表达式的编译规则。因此,DDLCompiler 包含一个访问器 sql_compiler,如下所示,我们生成一个嵌入了 SQL 表达式的 CHECK 约束:
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
kw['literal_binds'] = True
return "CONSTRAINT %s CHECK (%s)" % (
constraint.name,
ddlcompiler.sql_compiler.process(
constraint.expression, **kw)
)
在上面的例子中,我们在由 SQLCompiler.process() 调用的处理步骤中添加了一个额外的标志,即 literal_binds 标志。这表示任何引用 BindParameter 对象或其他“文字”对象(如引用字符串或整数的对象)的 SQL 表达式应该就地渲染,而不是作为一个绑定参数引用;在发出 DDL 时,通常不支持绑定参数。
在 SQL 和 DDL 编译器之间进行交叉编译
SQL 和 DDL 构造使用不同的基础编译器 - SQLCompiler 和 DDLCompiler 进行编译。常见的需要是从 DDL 表达式中访问 SQL 表达式的编译规则。因此,DDLCompiler 包含一个访问器 sql_compiler,如下所示,我们生成一个嵌入了 SQL 表达式的 CHECK 约束:
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
kw['literal_binds'] = True
return "CONSTRAINT %s CHECK (%s)" % (
constraint.name,
ddlcompiler.sql_compiler.process(
constraint.expression, **kw)
)
在上面的例子中,我们在由 SQLCompiler.process() 调用的处理步骤中添加了一个额外的标志,即 literal_binds 标志。这表示任何引用 BindParameter 对象或其他“文字”对象(如引用字符串或整数的对象)的 SQL 表达式应该就地渲染,而不是作为一个绑定参数引用;在发出 DDL 时,通常不支持绑定参数。
更改现有构造的默认编译
编译器扩展同样适用于现有构造。当重写内置 SQL 构造的编译时,@compiles 装饰器会在适当的类上调用(确保使用类,即 Insert 或 Select,而不是创建函数,如 insert() 或 select())。
在新的编译函数中,要获取“原始”编译例程,使用适当的 visit_XXX 方法 - 这是因为编译器.process() 将调用重写例程并导致无限循环。例如,要向所有插入语句添加“前缀”:
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def prefix_inserts(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with("some prefix"), **kw)
上述编译器在编译时将所有 INSERT 语句前缀为“some prefix”。
更改类型的编译
compiler 也适用于类型,比如下面我们为 String/VARCHAR 实现 MS-SQL 特定的 ‘max’ 关键字:
@compiles(String, 'mssql')
@compiles(VARCHAR, 'mssql')
def compile_varchar(element, compiler, **kw):
if element.length == 'max':
return "VARCHAR('max')"
else:
return compiler.visit_VARCHAR(element, **kw)
foo = Table('foo', metadata,
Column('data', VARCHAR('max'))
)
子类指南
使用编译器扩展的一个重要部分是子类化 SQLAlchemy 表达式构造。为了使这更容易,表达式和模式包含一组用于常见任务的“基类”。概要如下:
-
ClauseElement- 这是根表达式类。任何 SQL 表达式都可以从这个基类派生,对于像专门的 INSERT 语句这样的较长构造来说,这可能是最好的选择。 -
ColumnElement- 所有“列样”元素的根。您在 SELECT 语句的“columns”子句中(以及 order by 和 group by)中放置的任何内容都可以从这里派生 - 该对象将自动具有 Python 的“比较”行为。ColumnElement类希望有一个type成员,该成员是表达式的返回类型。这可以在构造函数的实例级别或在类级别(如果通常是常量)中建立:class timestamp(ColumnElement): type = TIMESTAMP() inherit_cache = True -
FunctionElement- 这是ColumnElement和“from clause”类似对象的混合体,表示 SQL 函数或存储过程类型的调用。由于大多数数据库支持类似“SELECT FROM”的语句, FunctionElement添加了在select()构造的 FROM 子句中使用的能力:from sqlalchemy.sql.expression import FunctionElement class coalesce(FunctionElement): name = 'coalesce' inherit_cache = True @compiles(coalesce) def compile(element, compiler, **kw): return "coalesce(%s)" % compiler.process(element.clauses, **kw) @compiles(coalesce, 'oracle') def compile(element, compiler, **kw): if len(element.clauses) > 2: raise TypeError("coalesce only supports two arguments on Oracle") return "nvl(%s)" % compiler.process(element.clauses, **kw) -
ExecutableDDLElement- 所有 DDL 表达式的根,比如 CREATE TABLE,ALTER TABLE 等。ExecutableDDLElement的子类的编译由DDLCompiler发出,而不是SQLCompiler。ExecutableDDLElement还可以与诸如DDLEvents.before_create()和DDLEvents.after_create()等事件钩子一起用作事件钩子,允许在 CREATE TABLE 和 DROP TABLE 序列期间自动调用构造。另请参阅
自定义 DDL - 包含将
DDL对象(它们本身是ExecutableDDLElement实例)与DDLEvents事件钩子相关联的示例。 -
Executable- 这是一个混合类,应该与表示“独立”SQL 语句的任何表达式类一起使用,可以直接传递给execute()方法。 它已经隐式地存在于DDLElement和FunctionElement中。
上述大多数构造也会响应 SQL 语句缓存。 子类化的构造将希望为对象定义缓存行为,这通常意味着将标志 inherit_cache 设置为 False 或 True 的值。 有关背景信息,请参见下一节 为自定义构造启用缓存支持。
为自定义构造启用缓存支持
截至版本 1.4,SQLAlchemy 包括一个 SQL 编译缓存功能,它将允许等效的 SQL 构造缓存它们的字符串形式,以及用于从语句获取结果的其他结构信息。
由于讨论的原因在对象不会生成缓存键,性能影响,这个缓存系统的实现采用了一种保守的方式来包括自定义 SQL 构造和/或子类在缓存系统中。这包括任何用户定义的 SQL 构造,包括此扩展的所有示例,默认情况下将不参与缓存,除非它们明确声明能够参与缓存。当HasCacheKey.inherit_cache属性在特定子类的类级别上设置为True时,将表示此类的实例可以安全地缓存,使用其直接超类的缓存键生成方案。例如,这适用于先前指示的“概要”示例:
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
在上述示例中,MyColumn 类不包含任何影响其 SQL 编译的新状态;MyColumn 实例的缓存键将利用 ColumnClause 超类的缓存键,这意味着它将考虑对象的类(MyColumn)、对象的字符串名称和数据类型:
>>> MyColumn("some_name", String())._generate_cache_key()
CacheKey(
key=('0', <class '__main__.MyColumn'>,
'name', 'some_name',
'type', (<class 'sqlalchemy.sql.sqltypes.String'>,
('length', None), ('collation', None))
), bindparams=[])
对于可能在许多较大语句中自由使用的对象,例如 Column 子类和自定义 SQL 数据类型,尽可能启用缓存是很重要的,否则可能会对性能产生负面影响。
一个包含影响其 SQL 编译的状态的对象示例是在编译自定义表达式结构的子元素中所示的对象;这是一个将 Table 与 Select 构造组合在一起的“INSERT FROM SELECT”构造,它们各自独立地影响构造的 SQL 字符串生成。对于这个类,示例说明了它根本不参与缓存:
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
)
虽然上述的 InsertFromSelect 也可能生成由 Table 和 Select 组件组成的缓存键,但目前该 API 并不完全公开。但是,对于“INSERT FROM SELECT”构造,它只用于特定操作,缓存并不像前面的示例那样关键。
对于在相对孤立并且通常是独立的对象,比如自定义 DML 构造,比如“INSERT FROM SELECT”,缓存通常不太关键,因为对于这种构造物的缺乏缓存只会对该特定操作产生局部影响。
更多示例
“UTC 时间戳”函数
一个类似于“CURRENT_TIMESTAMP”的函数,但应用适当的转换,使时间处于 UTC 时间。时间戳最好存储在关系数据库中作为 UTC 时间,不带时区。UTC 时间是为了在夏令时结束时,数据库不会认为时间倒退一小时,不带时区是因为时区就像字符编码一样——最好只在应用程序的端点应用(即在用户输入时转换为 UTC 时间,在显示时重新应用所需的时区)。
对于 PostgreSQL 和 Microsoft SQL Server:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
class utcnow(expression.FunctionElement):
type = DateTime()
inherit_cache = True
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
@compiles(utcnow, 'mssql')
def ms_utcnow(element, compiler, **kw):
return "GETUTCDATE()"
示例用法:
from sqlalchemy import (
Table, Column, Integer, String, DateTime, MetaData
)
metadata = MetaData()
event = Table("event", metadata,
Column("id", Integer, primary_key=True),
Column("description", String(50), nullable=False),
Column("timestamp", DateTime, server_default=utcnow())
)
“GREATEST”函数
“GREATEST”函数被赋予任意数量的参数,并返回具有最高值的参数——它等同于 Python 的max函数。一个 SQL 标准版本与一个基于 CASE 的版本相对应,后者仅容纳两个参数:
from sqlalchemy.sql import expression, case
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import Numeric
class greatest(expression.FunctionElement):
type = Numeric()
name = 'greatest'
inherit_cache = True
@compiles(greatest)
def default_greatest(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(greatest, 'sqlite')
@compiles(greatest, 'mssql')
@compiles(greatest, 'oracle')
def case_greatest(element, compiler, **kw):
arg1, arg2 = list(element.clauses)
return compiler.process(case((arg1 > arg2, arg1), else_=arg2), **kw)
示例用法:
Session.query(Account).\
filter(
greatest(
Account.checking_balance,
Account.savings_balance) > 10000
)
“false”表达式
渲染“false”常量表达式,在没有“false”常量的平台上呈现为“0”:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
class sql_false(expression.ColumnElement):
inherit_cache = True
@compiles(sql_false)
def default_false(element, compiler, **kw):
return "false"
@compiles(sql_false, 'mssql')
@compiles(sql_false, 'mysql')
@compiles(sql_false, 'oracle')
def int_false(element, compiler, **kw):
return "0"
示例用法:
from sqlalchemy import select, union_all
exp = union_all(
select(users.c.name, sql_false().label("enrolled")),
select(customers.c.name, customers.c.enrolled)
)
“UTC 时间戳”函数
一个类似于“CURRENT_TIMESTAMP”的函数,但应用适当的转换,使时间处于 UTC 时间。时间戳最好存储在关系数据库中作为 UTC 时间,不带时区。UTC 时间是为了在夏令时结束时,数据库不会认为时间倒退一小时,不带时区是因为时区就像字符编码一样——最好只在应用程序的端点应用(即在用户输入时转换为 UTC 时间,在显示时重新应用所需的时区)。
对于 PostgreSQL 和 Microsoft SQL Server:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
class utcnow(expression.FunctionElement):
type = DateTime()
inherit_cache = True
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
@compiles(utcnow, 'mssql')
def ms_utcnow(element, compiler, **kw):
return "GETUTCDATE()"
示例用法:
from sqlalchemy import (
Table, Column, Integer, String, DateTime, MetaData
)
metadata = MetaData()
event = Table("event", metadata,
Column("id", Integer, primary_key=True),
Column("description", String(50), nullable=False),
Column("timestamp", DateTime, server_default=utcnow())
)
“GREATEST”函数
“GREATEST”函数被赋予任意数量的参数,并返回具有最高值的参数——它等同于 Python 的max函数。一个 SQL 标准版本与一个基于 CASE 的版本相对应,后者仅容纳两个参数:
from sqlalchemy.sql import expression, case
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import Numeric
class greatest(expression.FunctionElement):
type = Numeric()
name = 'greatest'
inherit_cache = True
@compiles(greatest)
def default_greatest(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(greatest, 'sqlite')
@compiles(greatest, 'mssql')
@compiles(greatest, 'oracle')
def case_greatest(element, compiler, **kw):
arg1, arg2 = list(element.clauses)
return compiler.process(case((arg1 > arg2, arg1), else_=arg2), **kw)
示例用法:
Session.query(Account).\
filter(
greatest(
Account.checking_balance,
Account.savings_balance) > 10000
)
“false”表达式
渲染“false”常量表达式,在没有“false”常量的平台上呈现为“0”:
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
class sql_false(expression.ColumnElement):
inherit_cache = True
@compiles(sql_false)
def default_false(element, compiler, **kw):
return "false"
@compiles(sql_false, 'mssql')
@compiles(sql_false, 'mysql')
@compiles(sql_false, 'oracle')
def int_false(element, compiler, **kw):
return "0"
示例用法:
from sqlalchemy import select, union_all
exp = union_all(
select(users.c.name, sql_false().label("enrolled")),
select(customers.c.name, customers.c.enrolled)
)


浙公网安备 33010602011771号