SqlAlchemy 2.0 中文文档(三十五)(3)

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

SqlAlchemy 2.0 中文文档(三十五)(2)https://developer.aliyun.com/article/1562892


示例 4,嵌套 CTE(SQLAlchemy 1.4.24 及以上):

value_a = select(
    literal("root").label("n")
).cte("value_a")
# A nested CTE with the same name as the root one
value_a_nested = select(
    literal("nesting").label("n")
).cte("value_a", nesting=True)
# Nesting CTEs takes ascendency locally
# over the CTEs at a higher level
value_b = select(value_a_nested.c.n).cte("value_b")
value_ab = select(value_a.c.n.label("a"), value_b.c.n.label("b"))

上述查询将呈现第二个 CTE 嵌套在第一个内部,如下所示:

WITH
    value_a AS
        (SELECT 'root' AS n),
    value_b AS
        (WITH value_a AS
            (SELECT 'nesting' AS n)
        SELECT value_a.n AS n FROM value_a)
SELECT value_a.n AS a, value_b.n AS b
FROM value_a, value_b

可以使用HasCTE.add_cte()方法设置相同的 CTE,如下所示(SQLAlchemy 2.0 及以上):

value_a = select(
    literal("root").label("n")
).cte("value_a")
# A nested CTE with the same name as the root one
value_a_nested = select(
    literal("nesting").label("n")
).cte("value_a")
# Nesting CTEs takes ascendency locally
# over the CTEs at a higher level
value_b = (
    select(value_a_nested.c.n).
    add_cte(value_a_nested, nest_here=True).
    cte("value_b")
)
value_ab = select(value_a.c.n.label("a"), value_b.c.n.label("b"))

示例 5,非线性 CTE(SQLAlchemy 1.4.28 及以上):

edge = Table(
    "edge",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("left", Integer),
    Column("right", Integer),
)
root_node = select(literal(1).label("node")).cte(
    "nodes", recursive=True
)
left_edge = select(edge.c.left).join(
    root_node, edge.c.right == root_node.c.node
)
right_edge = select(edge.c.right).join(
    root_node, edge.c.left == root_node.c.node
)
subgraph_cte = root_node.union(left_edge, right_edge)
subgraph = select(subgraph_cte)

上述查询将在递归 CTE 内呈现 2 个 UNION:

WITH RECURSIVE nodes(node) AS (
        SELECT 1 AS node
    UNION
        SELECT edge."left" AS "left"
        FROM edge JOIN nodes ON edge."right" = nodes.node
    UNION
        SELECT edge."right" AS "right"
        FROM edge JOIN nodes ON edge."left" = nodes.node
)
SELECT nodes.node FROM nodes

另请参见

Query.cte() - HasCTE.cte()的 ORM 版本。

method distinct(*expr: _ColumnExpressionArgument[Any]) → Self

返回一个新的select()构造,该构造将对整个 SELECT 语句应用 DISTINCT。

例如:

from sqlalchemy import select
stmt = select(users_table.c.id, users_table.c.name).distinct()

上述将产生类似于的语句:

SELECT DISTINCT user.id, user.name FROM user

该方法还接受一个*expr参数,该参数生成 PostgreSQL 特定的DISTINCT ON表达式。在不支持此语法的���他后端上使用此参数将引发错误。

参数:

*expr

可选的列表达式。当存在时,PostgreSQL 方言将呈现DISTINCT ON ()构造。在其他后端上将引发弃用警告和/或CompileError

从版本 1.4 开始弃用:在其他方言中使用*expr 已弃用,并将在将来的版本中引发CompileError

method except_(*other: _SelectStatementForCompoundArgument) → CompoundSelect

返回此select()构造与提供的可选参数中的给定可选择的 SQLEXCEPT

参数:

*other

一个或多个用于创建 UNION 的元素。

从版本 1.4.28 开始更改:现在接受多个元素。

method except_all(*other: _SelectStatementForCompoundArgument) → CompoundSelect

返回此select()构造与提供的可选参数中的给定可选择的 SQLEXCEPT ALL

参数:

*other

一个或多个用于创建 UNION 的元素。

从版本 1.4.28 开始更改:现在接受多个元素。

method execution_options(**kw: Any) → Self

继承自 Executable.execution_options() 方法的 Executable

为在执行期间生效的语句设置非 SQL 选项。

可以在许多范围内设置执行选项,包括每个语句、每个连接或每次执行,使用诸如Connection.execution_options()和接受选项字典的参数的方法,例如Connection.execute.execution_optionsSession.execute.execution_options

与其他类型的选项(如 ORM 加载程序选项)相比,执行选项的主要特征是执行选项从不影响查询的编译 SQL,只影响 SQL 语句本身如何调用或结果如何获取。也就是说,执行选项不是 SQL 编译所能容纳的内容,它们也不被认为是语句的缓存状态的一部分。

Executable.execution_options() 方法是生成的,就像应用于EngineQuery对象的方法一样,这意味着当调用该方法时,将返回对象的副本,该副本应用给定的参数,但原始对象保持不变:

statement = select(table.c.x, table.c.y)
new_statement = statement.execution_options(my_option=True)

这种行为的一个例外是Connection对象,在这种情况下,Connection.execution_options() 方法明确是生成的。

可以传递给Executable.execution_options()和其他相关方法和参数字典的选项类型包括被 SQLAlchemy Core 或 ORM 明确消耗的参数,以及 SQLAlchemy 未定义的任意关键字参数,这意味着这些方法和/或参数字典可用于与自定义代码交互的用户定义参数,可以使用诸如Executable.get_execution_options()Connection.get_execution_options()等方法访问参数,或者在选定的事件钩子中使用专用的execution_options事件参数,例如ConnectionEvents.before_execute.execution_optionsORMExecuteState.execution_options,例如:

from sqlalchemy import event
@event.listens_for(some_engine, "before_execute")
def _process_opt(conn, statement, multiparams, params, execution_options):
    "run a SQL function before invoking a statement"
    if execution_options.get("do_special_thing", False):
        conn.exec_driver_sql("run_special_function()")

在 SQLAlchemy 明确识别的选项范围内,大多数适用于特定类别的对象而不是其他对象。最常见的执行选项包括:

  • Connection.execution_options.isolation_level - 通过Engine为连接或一类连接设置隔离级别。此选项仅被ConnectionEngine接受。
  • Connection.execution_options.stream_results - 表示结果应该使用服务器端游标获取;此选项可被ConnectionConnection.execute.execution_options参数上的Connection.execute()以及Executable.execution_options()在 SQL 语句对象上接受,同样也被 ORM 构造如Session.execute()接受。
  • Connection.execution_options.compiled_cache - 表示将作为ConnectionEngine的 SQL 编译缓存的字典,同样也适用于 ORM 方法如Session.execute()。可以传递None来禁用语句的缓存。此选项不被Executable.execution_options()接受,因为在语句对象中携带编译缓存是不明智的。
  • Connection.execution_options.schema_translate_map - 由模式翻译映射功能使用的模式名称映射,被ConnectionEngineExecutable接受,同样也被 ORM 构造如Session.execute()接受。

另请参阅

Connection.execution_options()

Connection.execute.execution_options

Session.execute.execution_options

ORM 执行选项 - 所有 ORM 特定执行选项的文档

method exists() → Exists

继承自 SelectBase.exists() 方法的 SelectBase

返回此可选择项的Exists表示,可用作列表达式。

返回的对象是Exists的一个实例。

另请参阅

exists()

EXISTS 子查询 - 在 2.0 风格教程中。

版本 1.4 中新增。

attribute exported_columns

继承自 SelectBase.exported_columns 属性的 SelectBase

代表此Selectable的“导出”列的ColumnCollection,不包括TextClause构造。

SelectBase对象的“导出”列与SelectBase.selected_columns集合是同义词。

版本 1.4 中新增。

另请参阅

Select.exported_columns

Selectable.exported_columns

FromClause.exported_columns

method fetch(count: _LimitOffsetType, with_ties: bool = False, percent: bool = False) → Self

继承自 GenerativeSelect.fetch() 方法的 GenerativeSelect

返回一个应用了给定 FETCH FIRST 标准的新可选择项。

此为数值,通常在生成的选择中以 FETCH {FIRST | NEXT} [ count ] {ROW | ROWS} {ONLY | WITH TIES} 表达式的形式呈现。此功能目前已实现在 Oracle、PostgreSQL 和 MSSQL 中。

使用 GenerativeSelect.offset() 指定偏移量。

注意

GenerativeSelect.fetch() 方法将替换任何使用 GenerativeSelect.limit() 应用的子句。

新版本 1.4 中新增。

参数:

  • count – 整数 COUNT 参数,或提供整数结果的 SQL 表达式。当 percent=True 时,这将表示要返回的行的百分比,而不是绝对值。传递 None 以重置它。
  • with_ties – 当为 True 时,使用 WITH TIES 选项以返回与 ORDER BY 子句中的最后一个位置并列的任何附加行。在这种情况下,ORDER BY 可能是强制性的。默认为 False
  • percent – 当为 True 时,count 表示要返回的所选行的百分比。默认为 False

另请参阅

GenerativeSelect.limit()

GenerativeSelect.offset()

method filter(*criteria: _ColumnExpressionArgument[bool]) → Self

Select.where() 方法的同义词。

method filter_by(**kwargs: Any) → Self

将给定的过滤条件作为 WHERE 子句应用于此选择。

method from_statement(statement: ReturnsRowsRole) → ExecutableReturnsRows

将此 Select 选择的列应用于另一个语句。

此操作是特定于插件的,如果此 Select 不选择来自启用插件的实体,则会引发不支持的异常。

语句通常是 text()select() 构造,并应返回适用于由此 Select 表示的实体的列集。

另请参阅

从文本语句获取 ORM 结果 - ORM 查询指南中的使用示例

attribute froms

返回显示的 FromClause 元素列表。

自版本 1.4.23 起已弃用:Select.froms 属性已移至 Select.get_final_froms() 方法。

method get_children(**kw: Any) → Iterable[ClauseElement]

返回此 HasTraverseInternals 的直接子元素。

这用于访问遍历。

**kw 可能包含改变返回集合的标志,例如返回一部分项目以减少更大的遍历,或者返回不同上下文的子项目(例如模式级别的集合而不是从句级别的集合)。

method get_execution_options() → _ExecuteOptions

继承自 Executable Executable.get_execution_options() 方法

获取在执行期间生效的非 SQL 选项。

自版本 1.3 起新增。

另请参见

Executable.execution_options()

method get_final_froms() → Sequence[FromClause]

计算最终显示的 FromClause 元素列表。

此方法将通过完整的计算来确定结果 SELECT 语句中将显示哪些 FROM 元素,包括用 JOIN 对象遮蔽单个表以及用于 ORM 使用情况的完整计算,包括急加载子句。

对于 ORM 使用,此访问器返回编译后的 FROM 对象列表;此集合将包括诸如急加载表和连接之类的元素。对象将被启用 ORM,并且不能作为 Select.select_froms() 集合的替代;此外,对于启用 ORM 语句,该方法的性能不佳,因为它将导致完整的 ORM 构造过程。

要检索由最初传递给 Select 的“列”集合隐含的 FROM 列表,请使用 Select.columns_clause_froms 访问器。

要从替代列集中选择而保持 FROM 列表,请使用 Select.with_only_columns() 方法,并传递 Select.with_only_columns.maintain_column_froms 参数。

1.4.23 版本中的新功能:- Select.get_final_froms() 方法取代了之前的 Select.froms 访问器,该访问器已被弃用。

另请参见

Select.columns_clause_froms

method get_label_style() → SelectLabelStyle

继承自 GenerativeSelect.get_label_style() 方法的 GenerativeSelect

检索当前标签样式。

1.4 版本中的新功能。

method group_by(_GenerativeSelect__first: Literal[None, _NoArg.NO_ARG] | _ColumnExpressionOrStrLabelArgument[Any] = _NoArg.NO_ARG, *clauses: _ColumnExpressionOrStrLabelArgument[Any]) → Self

继承自 GenerativeSelect.group_by() 方法的 GenerativeSelect

返回一个具有给定的 GROUP BY 准则列表的新的可选择项。

通过传递None可以取消所有现有的 GROUP BY 设置。

例如:

stmt = select(table.c.name, func.max(table.c.stat)).\
group_by(table.c.name)

参数:

*clauses – 一系列ColumnElement构造,将用于生成 GROUP BY 子句。

另请参见

GROUP BY / HAVING 中的聚合函数 - 在 SQLAlchemy 统一教程中

按标签排序或分组 - 在 SQLAlchemy 统一教程中

method having(*having: _ColumnExpressionArgument[bool]) → Self

返回一个新的 select() 构造,其中包含给定表达式添加到其 HAVING 子句中,并通过 AND 连接到现有子句(如果有)。

attribute inherit_cache: bool | None = None

继承自 HasCacheKey.inherit_cache 属性的 HasCacheKey 实例

表示此HasCacheKey实例是否应使用其直接超类使用的缓存密钥生成方案。

该属性默认为None,表示一个构造尚未考虑是否适合参与缓存;这在功能上等同于将值设置为False,除了还会发出警告。

如果与此类本地属性以及不是其超类的属性无关的属性对应的 SQL 不会更改,则可以在特定类上将此标志设置为True

另请参见

为自定义构造启用缓存支持 - 为第三方或用户定义的 SQL 构造设置HasCacheKey.inherit_cache属性的一般指南。

attribute inner_columns

所有将被渲染到生成的 SELECT 语句的列子句中的ColumnElement表达式的迭代器。

从 1.4 版本开始,此方法已被弃用,并由Select.exported_columns集合取代。

method intersect(*other: _SelectStatementForCompoundArgument) → CompoundSelect

返回此 select()构造与作为位置参数提供的给定 selectables 的 SQL INTERSECT

参数:

  • *other
    一个或多个要创建联合的元素。
    自版本 1.4.28 起更改:现在接受多个元素。
  • **kwargs – 关键字参数将转发到新创建的CompoundSelect对象的构造函数。
method intersect_all(*other: _SelectStatementForCompoundArgument) → CompoundSelect

返回此 select()构造与作为位置参数提供的给定 selectables 的 SQL INTERSECT ALL

参数:

  • *other
    一个或多个要创建联合的元素。
    自版本 1.4.28 起更改:现在接受多个元素。
  • **kwargs – 关键字参数将转发到新创建的CompoundSelect对象的构造函数。
method is_derived_from(fromclause: FromClause | None) → bool

如果此ReturnsRows是从给定的FromClause‘派生’,则返回True

一个示例是,表的别名是从该表派生的。

method join(target: _JoinTargetArgument, onclause: _OnClauseArgument | None = None, *, isouter: bool = False, full: bool = False) → Self

对此Select对象的条件进行 SQL JOIN,并应用生成,返回新生成的Select

例如:

stmt = select(user_table).join(address_table, user_table.c.id == address_table.c.user_id)

上述语句生成类似于以下的 SQL:

SELECT user.id, user.name FROM user JOIN address ON user.id = address.user_id

从版本 1.4 开始改变:Select.join() 现在在现有 SELECT 的 FROM 子句中创建一个 FromClause 源和给定目标 FromClause 之间的 Join 对象,然后将此 Join 添加到新生成的 SELECT 语句的 FROM 子句中。这完全重写自 1.3 中的行为,1.3 中的行为会创建一个整个 Select 的子查询,然后将该子查询连接到目标。

这是一个向后不兼容的更改,因为先前的行为大多是无用的,它会产生一个未命名的子查询,大多数数据库都会拒绝这种情况。新的行为是基于 ORM 中非常成功的 Query.join() 方法建模的,以支持使用具有 SessionSelect 对象可用的 Query 的功能。

有关此更改的注释,请参阅 select().join() 和 outerjoin() 向当前查询添加 JOIN 条件,而不是创建子查询。

参数:

  • target – 连接的目标表
  • onclause – 连接的 ON 子句。如果省略,则根据两个表之间的 ForeignKey 关系自动生成 ON 子句,如果可以明确确定,则引发错误。
  • isouter – 如果为 True,则生成 LEFT OUTER 连接。与 Select.outerjoin() 相同。
  • full – 如果为 True,则生成 FULL OUTER 连接。

另请参见

明确的 FROM 子句和 JOINs - 在 SQLAlchemy 统一教程 中

连接 - 在 ORM 查询指南 中

Select.join_from()

Select.outerjoin()

method join_from(from_: _FromClauseArgument, target: _JoinTargetArgument, onclause: _OnClauseArgument | None = None, *, isouter: bool = False, full: bool = False) → Self

对此Select对象的条件进行 SQL JOIN 并进行生成,返回新生成的Select

例如:

stmt = select(user_table, address_table).join_from(
    user_table, address_table, user_table.c.id == address_table.c.user_id
)

上述语句生成类似于以下的 SQL:

SELECT user.id, user.name, address.id, address.email, address.user_id
FROM user JOIN address ON user.id = address.user_id

1.4 版中的新功能。

参数:

  • from_ – 连接的左侧,在 FROM 子句中呈现,并且大致相当于使用Select.select_from()方法。
  • target – 向其连接的目标表
  • onclause – 连接的 ON 子句。
  • isouter – 如果为 True,则生成 LEFT OUTER 连接。与Select.outerjoin()相同。
  • full – 如果为 True,则生成 FULL OUTER 连接。

另请参阅

显式 FROM 子句和 JOINs - 在 SQLAlchemy 统一教程中

连接 - 在 ORM 查询指南中

Select.join()

method label(name: str | None) → Label[Any]

继承自 SelectBase.label() 方法的 SelectBase

返回此可选择的‘标量’表示,嵌入为具有标签的子查询。

另请参阅

SelectBase.scalar_subquery()

method lateral(name: str | None = None) → LateralFromClause

继承自 SelectBase.lateral() 方法的 SelectBase

返回此Selectable的 LATERAL 别名。

返回值也是顶级lateral()函数提供的Lateral构造。

另请参阅

横向相关性 - 用法概述。

method limit(limit: _LimitOffsetType) → Self

继承自 GenerativeSelect.limit() 方法的 GenerativeSelect

返回应用给定 LIMIT 条件的新可选择对象。

这是通常呈现为LIMIT表达式的数值值,不能支持LIMIT的后端将尝试提供类似的功能。

注意

GenerativeSelect.limit() 方法将替换使用 GenerativeSelect.fetch() 应用的任何子句。

参数:

limit – 一个整数 LIMIT 参数,或者提供整数结果的 SQL 表达式。传递 None 来重置它。

请参阅

GenerativeSelect.fetch()

GenerativeSelect.offset()

method offset(offset: _LimitOffsetType) → Self

继承自 GenerativeSelect.offset() 方法的 GenerativeSelect

返回一个应用了给定 OFFSET 条件的新可选择项。

这是一个数值,通常在结果选择中呈现为 OFFSET 表达式。不支持 OFFSET 的后端将尝试提供类似的功能。

参数:

offset – 一个整数 OFFSET 参数,或者提供整数结果的 SQL 表达式。传递 None 来重置它。

请参阅

GenerativeSelect.limit()

GenerativeSelect.fetch()

method options(*options: ExecutableOption) → Self

继承自 Executable.options() 方法的 Executable

将选项应用于此语句。

从一般意义上讲,选项是任何可以由 SQL 编译器解释为该语句的 Python 对象。这些选项可以被特定的方言或特定类型的编译器所使用。

最常见的选项类型是应用“急加载”和其他加载行为到 ORM 查询的 ORM 级选项。然而,选项理论上可以用于许多其他目的。

关于特定类型语句的特定类型选项的背景,请参阅这些选项对象的文档。

版本 1.4 中的变更:- 在核心语句对象中添加了Executable.options(),以实现统一的核心/ORM 查询功能的目标。

请参阅

列加载选项 - 指的是与 ORM 查询的使用相关的选项

使用加载器选项加载关系 - 指的是与 ORM 查询的使用相关的选项

method order_by(_GenerativeSelect__first: Literal[None, _NoArg.NO_ARG] | _ColumnExpressionOrStrLabelArgument[Any] = _NoArg.NO_ARG, *clauses: _ColumnExpressionOrStrLabelArgument[Any]) → Self

继承自 GenerativeSelect.order_by() 方法的 GenerativeSelect

返回一个应用给定的 ORDER BY 标准的新可选择对象。

例如:

stmt = select(table).order_by(table.c.id, table.c.name)

多次调用此方法等效于一次调用,其中所有子句都连接在一起。通过单独传递 None 可以取消所有现有的 ORDER BY 标准。然后可以通过再次调用 Query.order_by() 来添加新的 ORDER BY 标准,例如:

# will erase all ORDER BY and ORDER BY new_col alone
stmt = stmt.order_by(None).order_by(new_col)

参数:

*clauses – 一系列将用于生成 ORDER BY 子句的 ColumnElement 构造。

另请参见

ORDER BY - 在 SQLAlchemy 统一教程中

按标签排序或分组 - 在 SQLAlchemy 统一教程中

method outerjoin(target: _JoinTargetArgument, onclause: _OnClauseArgument | None = None, *, full: bool = False) → Self

创建一个左外连接。

参数与 Select.join() 相同。

从版本 1.4 开始:Select.outerjoin() 现在在现有 SELECT 的 FROM 子句中创建一个 Join 对象,以及一个给定的目标 FromClause,然后将这个 Join 添加到新生成的 SELECT 语句的 FROM 子句中。这与 1.3 版本中的行为完全不同,1.3 版本会创建整个 Select 的子查询,然后将该子查询连接到目标。

这是一个向后不兼容的更改,因为以前的行为大多是无用的,产生的无名称子查询在任何情况下都被大多数数据库拒绝。新的行为是模仿 ORM 中非常成功的 Query.join() 方法的行为,以支持通过使用带有 SessionSelect 对象来使 Query 的功能可用。

查看此更改的注释:select().join() 和 outerjoin() 将 JOIN 条件添加到当前查询,而不是创建子查询。

另请参阅

显式的 FROM 子句和 JOINs - 在 SQLAlchemy 统一教程 中

连接 - 在 ORM 查询指南 中

Select.join()

method outerjoin_from(from_: _FromClauseArgument, target: _JoinTargetArgument, onclause: _OnClauseArgument | None = None, *, full: bool = False) → Self

对此 Select 对象的条件创建一个 SQL LEFT OUTER JOIN 并进行生成,返回新生成的 Select

用法与 Select.join_from() 相同。

method prefix_with(*prefixes: _TextCoercedExpressionArgument[Any], dialect: str = '*') → Self

来自 HasPrefixes.prefix_with() 方法的继承 HasPrefixes

在语句关键字(如 SELECT、INSERT、UPDATE 或 DELETE)之后添加一个或多个表达式。生成式。

这用于支持后端特定的前缀关键字,例如 MySQL 提供的那些。

例如:

stmt = table.insert().prefix_with("LOW_PRIORITY", dialect="mysql")
# MySQL 5.7 optimizer hints
stmt = select(table).prefix_with(
    "/*+ BKA(t1) */", dialect="mysql")

可以通过多次调用 HasPrefixes.prefix_with() 来指定多个前缀。

参数:

  • *prefixes – 文本或者ClauseElement 构造,将在 INSERT、UPDATE 或 DELETE 关键字之后呈现。
  • dialect – 可选的字符串方言名称,将限制该前缀的渲染仅适用于该方言。
method reduce_columns(only_synonyms: bool = True) → Select

从列子句中删除冗余命名但值等效的列,并返回一个新的 select() 构造。

这里的“冗余”指的是一个列引用另一个列,要么基于外键,要么通过语句的 WHERE 子句中的简单等式比较。此方法的主要目的是自动构造一个具有所有唯一命名列的选择语句,而无需像Select.set_label_style()那样使用表格限定标签。

当基于外键省略列时,保留的是所引用的列。当基于 WHERE 等价性省略列时,保留的是列子句中的第一列。

参数:

only_synonyms – 当为 True 时,限制删除与等效项同名的列。否则,删除所有与另一个等效项相同的列。

method replace_selectable(old: FromClause, alias: Alias) → Self

继承自 Selectable.replace_selectable() 方法的 Selectable

用给定的Alias对象替换所有FromClause ‘old’的出现,返回此FromClause的副本。

自 1.4 版本起已弃用:Selectable.replace_selectable()方法已弃用,并将在将来的版本中删除。类似的功能可通过 sqlalchemy.sql.visitors 模块获得。

method scalar_subquery() → ScalarSelect[Any]

继承自 SelectBase.scalar_subquery() 方法的 SelectBase

返回此可选择对象的“标量”表示,可用作列表达式。

返回的对象是ScalarSelect的实例。

通常,只有在其列子句中只有一个列的选择语句才有资格用作标量表达式。然后可以在封闭 SELECT 的 WHERE 子句或列子句中使用标量子查询。

请注意,标量子查询与使用SelectBase.subquery()方法生成的 FROM 级子查询有所不同。

参见

标量和相关子查询 - 在 2.0 教程中

method select(*arg: Any, **kw: Any) → Select

继承自 SelectBase.select() 方法的 SelectBase

自版本 1.4 弃用:SelectBase.select() 方法已弃用,并将在以后的版本中删除;该方法隐式创建了一个应显式的子查询。请首先调用 SelectBase.subquery() 以创建一个子查询,然后可以选择它。

method select_from(*froms: _FromClauseArgument) → Self

返回一个将给定的 FROM 表达式合并到其 FROM 对象列表中的新 select() 结构。

例如:

table1 = table('t1', column('a'))
table2 = table('t2', column('b'))
s = select(table1.c.a).\
    select_from(
        table1.join(table2, table1.c.a==table2.c.b)
    )

“from” 列表是根据每个元素的标识符组成的唯一集合,因此添加一个已经存在的 Table 或其他可选项将不会产生任何影响。传递一个指向已经存在的 Table 或其他可选项的 Join 将隐藏该可选项的存在,而是将其呈现为 JOIN 子句中的单独元素。

虽然 Select.select_from() 的典型目的是用 JOIN 替换默认的派生 FROM 子句,但也可以调用它以单独的表元素,如果需要的话,多次调用,在无法从列子句完全派生 FROM 子句的情况下:

select(func.count('*')).select_from(table1)
attribute selected_columns

一个表示此 SELECT 语句或类似结构返回的结果集中的列的 ColumnCollection ,不包括 TextClause 结构。

此集合与 FromClause.columns 集合不同,因为此集合中的列不能直接嵌套在另一个 SELECT 语句内;必须首先应用一个子查询,该子查询提供了 SQL 所需的必要括号化。

对于select()构造,这里的集合正是在“SELECT”语句内部呈现的内容,ColumnElement对象直接按照给定的方式呈现,例如:

col1 = column('q', Integer)
col2 = column('p', Integer)
stmt = select(col1, col2)

在上面,stmt.selected_columns将是一个包含col1col2对象的集合。对于针对Table或其他FromClause的语句,集合将使用FromClause.c中的ColumnElement对象。

Select.selected_columns集合的一个用例是允许在添加额外条件时引用现有列,例如:

def filter_on_id(my_select, id):
    return my_select.where(my_select.selected_columns['id'] == id)
stmt = select(MyModel)
# adds "WHERE id=:param" to the statement
stmt = filter_on_id(stmt, 42)

注意

Select.selected_columns集合不包括在列子句中使用text()构造建立的表达式;这些将被静默地从集合中省略。要在Select构造内部使用纯文本列表达式,使用literal_column()构造。

版本 1.4 中的新功能。

method self_group(against: OperatorType | None = None) → SelectStatementGrouping | Self

对这个ClauseElement应用‘分组’。

此方法被子类重写以返回一个“分组”构造,即括号。特别是它被“二元”表达式使用,当放置到更大的表达式中时提供一个围绕自身的分组,以及当放置到另一个select()构造的 FROM 子句中时使用。(请注意,子查询通常应使用Select.alias()方法创建,因为许多平台要求嵌套的 SELECT 语句必须命名)。

随着表达式的组合,self_group() 的应用是自动的 - 最终用户代码不应直接使用此方法。请注意,SQLAlchemy 的子句构造会考虑运算符优先级 - 因此,例如,在表达式x OR (y AND z)中可能不需要括号 - AND 优先于 OR。

ClauseElement 的基础 self_group() 方法只是返回自身。

method set_label_style(style: SelectLabelStyle) → Self

继承自 GenerativeSelect.set_label_style() 方法的 GenerativeSelect

返回一个具有指定标签样式的新可选择对象。

有三种“标签样式”可用,SelectLabelStyle.LABEL_STYLE_DISAMBIGUATE_ONLYSelectLabelStyle.LABEL_STYLE_TABLENAME_PLUS_COLSelectLabelStyle.LABEL_STYLE_NONE。默认样式是 SelectLabelStyle.LABEL_STYLE_TABLENAME_PLUS_COL

在现代的 SQLAlchemy 中,通常不需要更改标签样式,因为通过使用 ColumnElement.label() 方法更有效地使用每个表达式的标签。在过去的版本中,LABEL_STYLE_TABLENAME_PLUS_COL 用于区分来自不同表、别名或子查询的同名列;新的 LABEL_STYLE_DISAMBIGUATE_ONLY 仅将标签应用于与现有名称冲突的名称,以使此标记的影响最小化。

区分的理由主要是为了在创建子查询时,所有列表达式都可以从给定的 FromClause.c 集合中使用。

新版本 1.4 中:GenerativeSelect.set_label_style()方法取代了以前的.apply_labels().with_labels()use_labels=True方法和/或参数的组合。

另请参阅

LABEL_STYLE_DISAMBIGUATE_ONLY

LABEL_STYLE_TABLENAME_PLUS_COL

LABEL_STYLE_NONE

LABEL_STYLE_DEFAULT

method slice(start: int, stop: int) → Self

继承自 GenerativeSelect.slice() 方法的 GenerativeSelect

根据切片将 LIMIT / OFFSET 应用于此语句。

开始和停止索引的行为类似于 Python 内置的range()函数的参数。该方法提供了一种使用LIMIT/OFFSET来获取查询片段的替代方法。

例如,

stmt = select(User).order_by(User).id.slice(1, 3)

呈现为

SELECT  users.id  AS  users_id,
  users.name  AS  users_name
FROM  users  ORDER  BY  users.id
LIMIT  ?  OFFSET  ?
(2,  1)

注意

GenerativeSelect.slice()方法将替换任何应用于GenerativeSelect.fetch()的子句。

新版本 1.4 中:从 ORM 推广出GenerativeSelect.slice()方法。

另请参阅

GenerativeSelect.limit()

GenerativeSelect.offset()

GenerativeSelect.fetch()

method subquery(name: str | None = None) → Subquery

继承自 SelectBase.subquery() 方法的 SelectBase

返回此 SelectBase 的子查询。

从 SQL 的角度来看,子查询是一种带有括号的命名构造,可以放置在另一个 SELECT 语句的 FROM 子句中。

给定如下 SELECT 语句:

stmt = select(table.c.id, table.c.name)

上述语句看起来可能像这样:

SELECT table.id, table.name FROM table

子查询本身以相同方式呈现,但是当嵌入到另一个 SELECT 语句的 FROM 子句中时,它就变成了一个命名子元素:

subq = stmt.subquery()
new_stmt = select(subq)

上述呈现为:

SELECT anon_1.id, anon_1.name
FROM (SELECT table.id, table.name FROM table) AS anon_1

历史上,SelectBase.subquery() 等同于在 FROM 对象上调用 FromClause.alias() 方法;然而,由于 SelectBase 对象不是直接的 FROM 对象,所以 SelectBase.subquery() 方法提供了更清晰的语义。

新版本中新增。

method suffix_with(*suffixes: _TextCoercedExpressionArgument[Any], dialect: str = '*') → Self

继承自 HasSuffixes.suffix_with() 方法的 HasSuffixes

在语句之后添加一个或多个表达式。

这用于支持在某些结构上的特定于后端的后缀关键字。

例如:

stmt = select(col1, col2).cte().suffix_with(
    "cycle empno set y_cycle to 1 default 0", dialect="oracle")

可以通过多次调用HasSuffixes.suffix_with()来指定多个后缀。

参数:

  • *suffixes – 将在目标子句之后呈现的文本或ClauseElement构造。
  • dialect – 可选的字符串方言名称,将此后缀的渲染限制为仅限于该方言。
method union(*other: _SelectStatementForCompoundArgument) → CompoundSelect

返回此 select() 构造相对于作为位置参数提供的给定可选择对象的 SQL UNION

参数:

  • *other
    用于创建 UNION 的一个或多个元素。
    从版本 1.4.28 开始更改:现在接受多个元素。
  • **kwargs – 关键字参数将转发到新创建的CompoundSelect对象的构造函数。
method union_all(*other: _SelectStatementForCompoundArgument) → CompoundSelect

返回此 select() 构造相对于作为位置参数提供的给定可选择对象的 SQL UNION ALL

参数:

  • *other
    用于创建 UNION 的一个或多个元素。
    从版本 1.4.28 开始更改:现在接受多个元素。
  • **kwargs – 关键字参数将转发到新创建的CompoundSelect对象的构造函数。
method where(*whereclause: _ColumnExpressionArgument[bool]) → Self

返回一个新的 select() 构造,其中给定的表达式添加到其 WHERE 子句中,并通过 AND 连接到现有子句(如果有)。

attribute whereclause

返回此 Select 语句的完成 WHERE 子句。

将当前的 WHERE 条件集合装配成一个单个的 BooleanClauseList 构造。

新版本中新增。

method with_for_update(*, nowait: bool = False, read: bool = False, of: _ForUpdateOfArgument | None = None, skip_locked: bool = False, key_share: bool = False) → Self

继承自 GenerativeSelect.with_for_update() 方法的 GenerativeSelect

为此 GenerativeSelect 指定一个 FOR UPDATE 子句。

例如:

stmt = select(table).with_for_update(nowait=True)

在像 PostgreSQL 或 Oracle 这样的数据库上,上述内容会呈现为如下语句:

SELECT table.a, table.b FROM table FOR UPDATE NOWAIT

在其他后端上,nowait 选项被忽略,而会产生:

SELECT table.a, table.b FROM table FOR UPDATE

当不带参数调用时,语句将以后缀 FOR UPDATE 呈现。然后可以提供其他参数,以允许常见的特定于数据库的变体。

参数:

  • nowait – 布尔值;将在 Oracle 和 PostgreSQL 方言上呈现 FOR UPDATE NOWAIT
  • read – 布尔值;将在 MySQL 上呈现 LOCK IN SHARE MODE,在 PostgreSQL 上呈现 FOR SHARE。在 PostgreSQL 上,当与 nowait 结合使用时,将呈现 FOR SHARE NOWAIT
  • of – SQL 表达式或 SQL 表达式元素的列表(通常是 Column 对象或兼容的表达式,对于某些后端也可能是表达式),它们将呈现为 FOR UPDATE OF 子句;由 PostgreSQL、Oracle、某些 MySQL 版本和可能其他后端支持。可能根据后端呈现为表或列。
  • skip_locked – 布尔值,将在 Oracle 和 PostgreSQL 方言上呈现 FOR UPDATE SKIP LOCKED,或者如果也指定了 read=True,则在 PostgreSQL 和 Oracle 方言上呈现 FOR SHARE SKIP LOCKED
  • key_share – 布尔值,将在 PostgreSQL 方言上呈现 FOR NO KEY UPDATE,或者如果与 read=True 结合使用,则在 PostgreSQL 方言上呈现 FOR KEY SHARE
method with_hint(selectable: _FromClauseArgument, text: str, dialect_name: str = '*') → Self

继承自 HasHints.with_hint() 方法的 HasHints

为给定的可选择项添加索引或其他执行上下文提示到此 Select 或其他可选择项对象。

提示文本会根据所使用的数据库后端,在相应的位置呈现,相对于传递给 selectable 参数的 TableAlias。方言实现通常使用 Python 字符串替换语法,使用标记 %(name)s 来呈现表或别名的名称。例如,在使用 Oracle 时,以下内容:

select(mytable).\
    with_hint(mytable, "index(%(name)s ix_mytable)")

会呈现 SQL 如下:

select /*+ index(mytable ix_mytable) */ ... from mytable

dialect_name 选项将限制特定提示的呈现到特定的后端。例如,同时为 Oracle 和 Sybase 添加提示:

select(mytable).\
    with_hint(mytable, "index(%(name)s ix_mytable)", 'oracle').\
    with_hint(mytable, "WITH INDEX ix_mytable", 'mssql')

另请参阅

Select.with_statement_hint()

method with_only_columns(*entities: _ColumnsClauseArgument[Any], maintain_column_froms: bool = False, **_Select__kw: Any) → Select[Any]

返回一个新的 select() 构造,其列子句替换为给定的实体。

默认情况下,这个方法与原始的 select() 被调用时给���的实体完全等效。例如,一个语句:

s = select(table1.c.a, table1.c.b)
s = s.with_only_columns(table1.c.b)

应该完全等效于:

s = select(table1.c.b)

在这种操作模式下,如果没有明确说明,Select.with_only_columns() 也会动态修改语句的 FROM 子句。为了保留当前列子句隐含的现有 FROM 集合,包括那些暗示的列子句,添加 Select.with_only_columns.maintain_column_froms 参数:

s = select(table1.c.a, table2.c.b)
s = s.with_only_columns(table1.c.a, maintain_column_froms=True)

上述参数将在列集合中的有效 FROM 转移到 Select.select_from() 方法中,就好像调用了以下内容:

s = select(table1.c.a, table2.c.b)
s = s.select_from(table1, table2).with_only_columns(table1.c.a)

Select.with_only_columns.maintain_column_froms 参数利用了 Select.columns_clause_froms 集合,并执行等效于以下操作:

s = select(table1.c.a, table2.c.b)
s = s.select_from(*s.columns_clause_froms).with_only_columns(table1.c.a)

参数:

  • *entities – 要使用的列表达式。
  • maintain_column_froms
    一个布尔参数,将确保从当前列子句暗示的 FROM 列表首先传递给 Select.select_from() 方法。
    从版本 1.4.23 开始。
method with_statement_hint(text: str, dialect_name: str = '*') → Self

继承自 HasHints.with_statement_hint() 方法的 HasHints

为这个 Select 或其他可选择对象添加一个语句提示。

这个方法类似于 Select.with_hint(),但不需要单独的表,而是应用于整个语句。

这里的提示是特定于后端数据库的,可能包括隔离级别、文件指令、提取指令等。

另请参阅

Select.with_hint()

Select.prefix_with() - 通用的 SELECT 前缀,也可以适用于一些特定于数据库的 HINT 语法,如 MySQL 优化提示

class sqlalchemy.sql.expression.Selectable

将一个类标记为可选择的。

成员

corresponding_column(), exported_columns, inherit_cache, is_derived_from(), lateral(), replace_selectable()

类签名

class sqlalchemy.sql.expression.Selectable (sqlalchemy.sql.expression.ReturnsRows)

method corresponding_column(column: KeyedColumnElement[Any], require_embedded: bool = False) → KeyedColumnElement[Any] | None

给定一个ColumnElement,从此Selectable.exported_columns的集合中返回与该原始ColumnElement通过共同祖先列相对应的导出ColumnElement对象。

参数:

  • column - 要匹配的目标ColumnElement
  • require_embedded - 仅返回给定的ColumnElement对应的列,如果给定的ColumnElement实际上存在于此Selectable的子元素中。通常,如果列仅与此Selectable的导出列之一共享共同的祖先,则列将匹配。

另请参阅

Selectable.exported_columns - 用于操作的ColumnCollection

ColumnCollection.corresponding_column() - 实现方法。

attribute exported_columns

继承自 ReturnsRows.exported_columns 属性 ReturnsRows

一个 ColumnCollection 代表了这个 ReturnsRows 的“导出”列。

“导出”列代表了这个 SQL 结构所呈现的 ColumnElement 表达式的集合。有主要的变体是 FROM 子句的“FROM 子句列”,例如表、连接或子查询,被“SELECT”列选中,这些列是 SELECT 语句的“columns clause”中的列,并且在 DML 语句中的 RETURNING 列。

1.4 版中的新内容。

另请参阅

FromClause.exported_columns

SelectBase.exported_columns

attribute inherit_cache: bool | None = None

继承自 HasCacheKey HasCacheKey.inherit_cache 属性

指示此 HasCacheKey 实例是否应该使用其直接超类使用的缓存键生成方案。

该属性默认为 None,表示构造尚未考虑它是否适合参与缓存;这在功能上等同于将值设置为 False,只是还会发出警告。

如果对象对应的 SQL 不会根据本类而不是其超类的属性而改变,那么可以将此标志设置为 True

另请参阅

为自定义结构启用缓存支持 - 为第三方或用户定义的 SQL 结构设置 HasCacheKey.inherit_cache 属性的一般指南。

method is_derived_from(fromclause: FromClause | None) → bool

继承自 ReturnsRows.is_derived_from() 方法 ReturnsRows

如果此ReturnsRows是从给定的FromClause“派生”出来,则返回True

一个示例是一个表的别名是从该表派生的。

method lateral(name: str | None = None) → LateralFromClause

返回此Selectable的 LATERAL 别名。

返回值是顶层lateral()函数提供的Lateral构造。

另请参阅

LATERAL 相关性 - 用法概述。

method replace_selectable(old: FromClause, alias: Alias) → Self

用给定的Alias对象替换所有FromClause‘old’的所有出现,返回此FromClause的副本。

自版本 1.4 起弃用:Selectable.replace_selectable()方法已弃用,并将在将来的版本中删除。类似功能可通过 sqlalchemy.sql.visitors 模块获得。

class sqlalchemy.sql.expression.SelectBase

SELECT 语句的基类。

这包括SelectCompoundSelectTextualSelect

成员

add_cte(), alias(), as_scalar(), c, corresponding_column(), cte(),  exists(), exported_columns, get_label_style(), inherit_cache,  is_derived_from(), label(), lateral(), replace_selectable(),  scalar_subquery(), select(), selected_columns, set_label_style(),  subquery()

类签名

sqlalchemy.sql.expression.SelectBase (sqlalchemy.sql.roles.SelectStatementRole, sqlalchemy.sql.roles.DMLSelectRole, sqlalchemy.sql.roles.CompoundElementRole, sqlalchemy.sql.roles.InElementRole, sqlalchemy.sql.expression.HasCTE, sqlalchemy.sql.annotation.SupportsCloneAnnotations, sqlalchemy.sql.expression.Selectable)

method add_cte(*ctes: CTE, nest_here: bool = False) → Self

继承自 HasCTE.add_cte() 方法的 HasCTE

向此语句添加一个或多个 CTE 构造。

此方法将给定的 CTE 构造与父语句关联,以便它们将在最终语句的 WITH 子句中无条件地呈现,即使在语句或任何子选择中没有其他地方引用它们。

可选的 HasCTE.add_cte.nest_here 参数设置为 True 时,每个给定的 CTE 将以一个 WITH 子句的形式直接与此语句一起呈现,而不是被移动到最终呈现语句的顶部,即使此语句作为一个子查询在较大的语句中被呈现。

此方法有两个通用用途。一个是嵌入一些没有被显式引用的 CTE 语句,比如将 DML 语句(比如 INSERT 或 UPDATE)作为  CTE 内联到一个主要语句中,这个主要语句可能间接地引用其结果。另一个是提供对一系列 CTE  构造的确切放置位置的控制,这些构造应该保持直接在一个特定语句中呈现,而这个语句可能嵌套在一个较大的语句中。

例如:

from sqlalchemy import table, column, select
t = table('t', column('c1'), column('c2'))
ins = t.insert().values({"c1": "x", "c2": "y"}).cte()
stmt = select(t).add_cte(ins)

将呈现为:

WITH anon_1 AS
(INSERT INTO t (c1, c2) VALUES (:param_1, :param_2))
SELECT t.c1, t.c2
FROM t

上面,“anon_1” CTE 在 SELECT 语句中没有被引用,但仍然完成了运行 INSERT 语句的任务。

类似地,在与 DML 相关的上下文中,使用 PostgreSQL 的 Insert 构造来生成“upsert”:

from sqlalchemy import table, column
from sqlalchemy.dialects.postgresql import insert
t = table("t", column("c1"), column("c2"))
delete_statement_cte = (
    t.delete().where(t.c.c1 < 1).cte("deletions")
)
insert_stmt = insert(t).values({"c1": 1, "c2": 2})
update_statement = insert_stmt.on_conflict_do_update(
    index_elements=[t.c.c1],
    set_={
        "c1": insert_stmt.excluded.c1,
        "c2": insert_stmt.excluded.c2,
    },
).add_cte(delete_statement_cte)
print(update_statement)

上面的语句呈现为:

WITH deletions AS
(DELETE FROM t WHERE t.c1 < %(c1_1)s)
INSERT INTO t (c1, c2) VALUES (%(c1)s, %(c2)s)
ON CONFLICT (c1) DO UPDATE SET c1 = excluded.c1, c2 = excluded.c2

1.4.21 版本中新增。

参数:

  • *ctes -
    零个或多个 CTE 构造。
    从 2.0 版本开始更改:接受多个 CTE 实例
  • nest_here -
    如果为 True,则给定的 CTE 或 CTEs 将被呈现为如果它们在被添加到此 HasCTE 时指定了 HasCTE.cte.nesting 标志为 True。假设给定的 CTEs 在外部封闭语句中也没有被引用,那么当给出此标志时,给定的 CTEs 应该在此语句的级别呈现。
    2.0 版本中新增。
    参见
    HasCTE.cte.nesting
method alias(name: str | None = None, flat: bool = False) → Subquery

返回针对此 SelectBase 的命名子查询。

对于 SelectBase(与 FromClause 相对),这将返回一个 Subquery 对象,其行为与与 FromClause 一起使用的 Alias 对象基本相同。

在 1.4 版本中更改:SelectBase.alias() 方法现在是 SelectBase.subquery() 方法的同义词。

method as_scalar() → ScalarSelect[Any]

自 1.4 版本起已弃用:SelectBase.as_scalar() 方法已弃用,并将在以后的版本中移除。请参考 SelectBase.scalar_subquery()

attribute c

自 1.4 版本起已弃用:SelectBase.cSelectBase.columns 属性已弃用,并将在以后的版本中移除;这些属性隐式创建一个应该明确的子查询。请首先调用 SelectBase.subquery() 来创建一个子查询,然后再使用此属性。要访问此 SELECT 对象从中选择的列,请使用 SelectBase.selected_columns 属性。

method corresponding_column(column: KeyedColumnElement[Any], require_embedded: bool = False) → KeyedColumnElement[Any] | None

继承自 Selectable.corresponding_column() 方法的 Selectable 对象

给定一个 ColumnElement,返回此 Selectable 的导出 ColumnElement 对象,该对象通过共同的祖先列与原始 ColumnElement 对应。

参数:

  • column – 要匹配的目标 ColumnElement
  • require_embedded – 仅返回给定 ColumnElement 的相应列,如果给定的 ColumnElement 实际上存在于此 Selectable 的子元素中。通常情况下,如果该列仅仅与此 Selectable 的导出列之一共享共同的祖先,则列将匹配。

另请参阅

Selectable.exported_columns - 用于操作的 ColumnCollection

ColumnCollection.corresponding_column() - 实现方法。

method cte(name: str | None = None, recursive: bool = False, nesting: bool = False) → CTE

继承自 HasCTE.cte() 方法的 HasCTE

返回一个新的 CTE,或通用表达式实例。

通用表达式(Common table expressions)是 SQL 标准的一部分,SELECT  语句可以在主语句的基础上引用指定的辅助语句,使用一个叫做“WITH”的子句。特殊的关于 UNION  的语义也可以被采用,以允许“递归”查询,其中一个 SELECT 语句可以引用之前已经被选定的行的集合。

CTEs 也可以应用于 DML 构造 UPDATE、INSERT 和 DELETE 在一些数据库上,既作为与 RETURNING 结合使用时的 CTE 行的来源,也作为 CTE 行的消费者。

SQLAlchemy 检测到 CTE 对象,它们被视为类似于 Alias 对象,作为特殊元素交付给语句的 FROM 子句以及语句顶部的 WITH 子句。

对于像 PostgreSQL 的“MATERIALIZED”和“NOT MATERIALIZED”这样的特殊前缀,可以使用 CTE.prefix_with() 方法来建立这些前缀。

版本 1.3.13 中的更改:增加了对前缀的支持。具体来说 - MATERIALIZED 和 NOT MATERIALIZED。

参数:

  • name – 给通用表达式的名称。像 FromClause.alias() 一样,名称可以保持为 None,在这种情况下,将在查询编译时使用一个匿名符号。
  • recursive – 如果True,将呈现WITH RECURSIVE。递归公共表达式旨在与 UNION ALL 结合使用,以从已选择的行中派生行。
  • nesting
    如果True,将在引用它的语句中本地呈现 CTE。对于更复杂的情况,也可以使用HasCTE.add_cte()方法,使用HasCTE.add_cte.nest_here参数更精确地控制特定 CTE 的确切放置。
    新版本 1.4.24。
    另请参阅
    HasCTE.add_cte()

以下示例包括两个来自 PostgreSQL 文档的示例,网址为 www.postgresql.org/docs/current/static/queries-with.html,以及其他示例。

示例 1,非递归:

from sqlalchemy import (Table, Column, String, Integer,
                        MetaData, select, func)
metadata = MetaData()
orders = Table('orders', metadata,
    Column('region', String),
    Column('amount', Integer),
    Column('product', String),
    Column('quantity', Integer)
)
regional_sales = select(
                    orders.c.region,
                    func.sum(orders.c.amount).label('total_sales')
                ).group_by(orders.c.region).cte("regional_sales")
top_regions = select(regional_sales.c.region).\
        where(
            regional_sales.c.total_sales >
            select(
                func.sum(regional_sales.c.total_sales) / 10
            )
        ).cte("top_regions")
statement = select(
            orders.c.region,
            orders.c.product,
            func.sum(orders.c.quantity).label("product_units"),
            func.sum(orders.c.amount).label("product_sales")
    ).where(orders.c.region.in_(
        select(top_regions.c.region)
    )).group_by(orders.c.region, orders.c.product)
result = conn.execute(statement).fetchall()

示例 2,WITH RECURSIVE:

from sqlalchemy import (Table, Column, String, Integer,
                        MetaData, select, func)
metadata = MetaData()
parts = Table('parts', metadata,
    Column('part', String),
    Column('sub_part', String),
    Column('quantity', Integer),
)
included_parts = select(\
    parts.c.sub_part, parts.c.part, parts.c.quantity\
    ).\
    where(parts.c.part=='our part').\
    cte(recursive=True)
incl_alias = included_parts.alias()
parts_alias = parts.alias()
included_parts = included_parts.union_all(
    select(
        parts_alias.c.sub_part,
        parts_alias.c.part,
        parts_alias.c.quantity
    ).\
    where(parts_alias.c.part==incl_alias.c.sub_part)
)
statement = select(
            included_parts.c.sub_part,
            func.sum(included_parts.c.quantity).
              label('total_quantity')
        ).\
        group_by(included_parts.c.sub_part)
result = conn.execute(statement).fetchall()

示例 3,使用 UPDATE 和 INSERT 进行 upsert 与 CTEs:

from datetime import date
from sqlalchemy import (MetaData, Table, Column, Integer,
                        Date, select, literal, and_, exists)
metadata = MetaData()
visitors = Table('visitors', metadata,
    Column('product_id', Integer, primary_key=True),
    Column('date', Date, primary_key=True),
    Column('count', Integer),
)
# add 5 visitors for the product_id == 1
product_id = 1
day = date.today()
count = 5
update_cte = (
    visitors.update()
    .where(and_(visitors.c.product_id == product_id,
                visitors.c.date == day))
    .values(count=visitors.c.count + count)
    .returning(literal(1))
    .cte('update_cte')
)
upsert = visitors.insert().from_select(
    [visitors.c.product_id, visitors.c.date, visitors.c.count],
    select(literal(product_id), literal(day), literal(count))
        .where(~exists(update_cte.select()))
)
connection.execute(upsert)

示例 4���嵌套 CTE(SQLAlchemy 1.4.24 及以上版本):

value_a = select(
    literal("root").label("n")
).cte("value_a")
# A nested CTE with the same name as the root one
value_a_nested = select(
    literal("nesting").label("n")
).cte("value_a", nesting=True)
# Nesting CTEs takes ascendency locally
# over the CTEs at a higher level
value_b = select(value_a_nested.c.n).cte("value_b")
value_ab = select(value_a.c.n.label("a"), value_b.c.n.label("b"))

上述查询将呈现第二个 CTE 嵌套在第一个内部,如下所示:

WITH
    value_a AS
        (SELECT 'root' AS n),
    value_b AS
        (WITH value_a AS
            (SELECT 'nesting' AS n)
        SELECT value_a.n AS n FROM value_a)
SELECT value_a.n AS a, value_b.n AS b
FROM value_a, value_b

可以使用以下方式设置相同的 CTE,使用HasCTE.add_cte()方法(SQLAlchemy 2.0 及以上版本):

value_a = select(
    literal("root").label("n")
).cte("value_a")
# A nested CTE with the same name as the root one
value_a_nested = select(
    literal("nesting").label("n")
).cte("value_a")
# Nesting CTEs takes ascendency locally
# over the CTEs at a higher level
value_b = (
    select(value_a_nested.c.n).
    add_cte(value_a_nested, nest_here=True).
    cte("value_b")
)
value_ab = select(value_a.c.n.label("a"), value_b.c.n.label("b"))

示例 5,非线性 CTE(SQLAlchemy 1.4.28 及以上版本):

edge = Table(
    "edge",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("left", Integer),
    Column("right", Integer),
)
root_node = select(literal(1).label("node")).cte(
    "nodes", recursive=True
)
left_edge = select(edge.c.left).join(
    root_node, edge.c.right == root_node.c.node
)
right_edge = select(edge.c.right).join(
    root_node, edge.c.left == root_node.c.node
)
subgraph_cte = root_node.union(left_edge, right_edge)
subgraph = select(subgraph_cte)

上述查询将在递归 CTE 内呈现 2 个 UNION:

WITH RECURSIVE nodes(node) AS (
        SELECT 1 AS node
    UNION
        SELECT edge."left" AS "left"
        FROM edge JOIN nodes ON edge."right" = nodes.node
    UNION
        SELECT edge."right" AS "right"
        FROM edge JOIN nodes ON edge."left" = nodes.node
)
SELECT nodes.node FROM nodes

另请参阅

Query.cte() - HasCTE.cte() 的 ORM 版本。

method exists() → Exists

返回此可选择的Exists表示,可用作列表达式。

返回的对象是Exists的实例。

另请参阅

exists()

EXISTS 子查询 - 在 2.0 风格教程中。

新版本 1.4。

attribute exported_columns

一个ColumnCollection,表示此Selectable的“导出”列,不包括TextClause构造。

SelectBase 对象的“导出”列与 SelectBase.selected_columns 集合是同义词。

版本 1.4 中的新功能。

另请参阅

Select.exported_columns

Selectable.exported_columns

FromClause.exported_columns

method get_label_style() → SelectLabelStyle

检索当前标签样式。

由子类实现。

attribute inherit_cache: bool | None = None

继承自 HasCacheKey HasCacheKey.inherit_cache *属性。

指示此 HasCacheKey 实例是否应使用其直接超类使用的缓存键生成方案。

该属性默认为None,表示构造尚未考虑其是否适合参与缓存;这在功能上等同于将值设置为False,只是还会发出警告。

如果与对象对应的 SQL 不会根据本类而不是其超类的属性而改变,则可以在特定类上将此标志设置为True

另请参阅

为自定义构造启用缓存支持 - 设置第三方或用户定义的 SQL 构造的 HasCacheKey.inherit_cache 属性的一般指南。

method is_derived_from(fromclause: FromClause | None) → bool

继承自 ReturnsRows ReturnsRows.is_derived_from() *方法。

如果此 ReturnsRows 是从给定的 FromClause ‘派生’,则返回True

一个示例是,表的别名是从该表派生的。

method label(name: str | None) → Label[Any]

返回此可选择项的“标量”表示,嵌入为带有标签的子查询。

另请参阅

SelectBase.scalar_subquery()

method lateral(name: str | None = None) → LateralFromClause

返回此 Selectable 的 LATERAL 别名。

返回值也是顶级lateral()函数提供的Lateral构造。

请参见

横向相关 - 用法概述。

method replace_selectable(old: FromClause, alias: Alias) → Self

继承自 Selectable.replace_selectable() 方法的 Selectable

将所有FromClause ‘old’的出现替换为给定的Alias对象,返回此FromClause的副本。

自版本 1.4 起不推荐使用:Selectable.replace_selectable() 方法已弃用,并将在将来的版本中删除。类似的功能可通过 sqlalchemy.sql.visitors 模块使用。

method scalar_subquery() → ScalarSelect[Any]

返回可用作列表达式的此可选择性的“标量”表示。

返回的对象是ScalarSelect的一个实例。

通常,在其列子句中只有一个列的 select 语句有资格用作标量表达式。然后可以在封闭 SELECT 的 WHERE 子句或列子句中使用标量子查询。

请注意,标量子查询与使用SelectBase.subquery() 方法生成的 FROM 级子查询不同。

请参见

标量和相关子查询 - 在 2.0 教程中

method select(*arg: Any, **kw: Any) → Select

自版本 1.4 起不推荐使用:SelectBase.select() 方法已弃用,并将在将来的版本中删除;此方法隐式创建应明确的子查询。请先调用 SelectBase.subquery() 以创建子查询,然后可以选择该子查询。

attribute selected_columns

表示此 SELECT 语句或类似构造返回的结果集中的列的 ColumnCollection

该集合与 FromClause.columns 集合不同之处在于,该集合中的列不能直接嵌套在另一个 SELECT 语句中;必须首先应用一个子查询,该子查询提供了 SQL 所需的必要括号。

注意

SelectBase.selected_columns 集合不包括使用 text() 构造在列子句中建立的表达式;这些表达式会被默默地从集合中省略掉。要在 Select 构造内使用纯文本列表达式,请使用 literal_column() 构造。

另请参阅

Select.selected_columns

版本 1.4 中新增。

method set_label_style(style: SelectLabelStyle) → Self

使用指定的标签样式返回新的可选择对象。

由子类实现。

method subquery(name: str | None = None) → Subquery

返回此 SelectBase 的子查询。

从 SQL 的角度来看,子查询是一种带有名称的括号括起来的构造,在另一个 SELECT 语句的 FROM 子句中可以放置。

给定如下 SELECT 语句:

stmt = select(table.c.id, table.c.name)

上述语句可能看起来像这样:

SELECT table.id, table.name FROM table

单独的子查询形式呈现方式相同,但是当嵌入到另一个 SELECT 语句的 FROM 子句中时,它就成为一个命名的子元素:

subq = stmt.subquery()
new_stmt = select(subq)

上述呈现为:

SELECT anon_1.id, anon_1.name
FROM (SELECT table.id, table.name FROM table) AS anon_1

从历史上看,SelectBase.subquery() 相当于在 FROM 对象上调用 FromClause.alias() 方法;然而,由于 SelectBase 对象不是直接的 FROM 对象,所以 SelectBase.subquery() 方法提供了更清晰的语义。

版本 1.4 中新增。

class sqlalchemy.sql.expression.Subquery

表示一个 SELECT 的子查询。

通过在任何包含 Select, CompoundSelect, 和 TextualSelectSelectBase 子类上调用 SelectBase.subquery() 方法或为方便起见调用 SelectBase.alias() 方法来创建 Subquery。在 FROM 子句中表示 SELECT 语句的主体部分,后面跟着通常的“AS ”,定义了所有“别名”对象。

Subquery 对象与 Alias 对象非常相似,并且可以以等效的方式使用。AliasSubquery 之间的区别在于 Alias 始终包含一个 FromClause 对象,而 Subquery 始终包含一个 SelectBase 对象。

新版本 1.4 中:添加了 Subquery 类,该类现在用于提供 SELECT 语句的别名版本。

成员

as_scalar(), inherit_cache

类签名

sqlalchemy.sql.expression.Subquery (sqlalchemy.sql.expression.AliasedReturnsRows)

method as_scalar() → ScalarSelect[Any]

自版本 1.4 起已弃用:Subquery.as_scalar()方法,在版本 1.4 之前曾是Alias.as_scalar(),已弃用并将在将来的版本中删除;请在构造子查询对象之前使用Select.scalar_subquery()方法的select()构造,或者在 ORM 中使用Query.scalar_subquery()方法。

attribute inherit_cache: bool | None = True

指示此HasCacheKey实例是否应使用其直接超类使用的缓存键生成方案。

该属性默认为None,表示构造尚未考虑是否适合参与缓存;这在功能上等同于将值设置为False,只是还会发出警告。

如果与对象对应的 SQL 不基于此类的本地属性而是其超类,则可以在特定类上将此标志设置为True

另请参见

为自定义构造启用缓存支持 - 设置第三方或用户定义的 SQL 构造的HasCacheKey.inherit_cache属性的一般指南。

class sqlalchemy.sql.expression.TableClause

表示一个最小的“表”构造。

这是一个轻量级的表对象,只有一个名称、一组列(通常由column()函数生成),以及一个模式:

from sqlalchemy import table, column
user = table("user",
        column("id"),
        column("name"),
        column("description"),
)

TableClause构造用作更常用的Table对象的基础,提供通常的FromClause服务,包括.c.集合和语句生成方法。

提供Table的所有附加模式级服务,包括约束、对其他表的引用,或者对MetaData级别服务的支持。它本身很有用,作为一种临时构造,用于在没有更完整的Table的情况下生成快速的 SQL 语句。

成员

alias(), c, columns, compare(), compile(), corresponding_column(),  delete(), description, entity_namespace, exported_columns, foreign_keys,  get_children(), implicit_returning, inherit_cache, insert(),  is_derived_from(), join(), lateral(), outerjoin(), params(),  primary_key, replace_selectable(), schema, select(), self_group(),  table_valued(), tablesample(), unique_params(), update()

类签名

class sqlalchemy.sql.expression.TableClause (sqlalchemy.sql.roles.DMLTableRole, sqlalchemy.sql.expression.Immutable, sqlalchemy.sql.expression.NamedFromClause)

method alias(name: str | None = None, flat: bool = False) → NamedFromClause

继承自 FromClause.alias() 方法的 FromClause

返回此FromClause的别名。

例如:

a2 = some_table.alias('a2')

上述代码创建了一个Alias对象,可以在任何 SELECT 语句中用作 FROM 子句。

请参阅

使用别名

alias()

attribute c

继承自 FromClause.c 属性的 FromClause

FromClause.columns的同义词

返回:

一个ColumnCollection

attribute columns

继承自 FromClause.columns 属性的 FromClause

由此FromClause维护的基于名称的ColumnElement对象的命名集合。

columnsc集合是使用绑定到表或其他可选择列构建 SQL 表达式的入口:

select(mytable).where(mytable.c.somecolumn == 5)

返回:

一个ColumnCollection对象。

method compare(other: ClauseElement, **kw: Any) → bool

继承自 ClauseElement.compare() 方法的 ClauseElement

将此ClauseElement与给定的ClauseElement进行比较。

子类应该重写默认行为,即直接的身份比较。

**kw 是子类compare()方法消耗的参数,可以用来修改比较的标准(参见ColumnElement)。

method compile(bind: _HasDialect | None = None, dialect: Dialect | None = None, **kw: Any) → Compiled

继承自 CompilerElement.compile() 方法的 CompilerElement

编译此 SQL 表达式。

返回值是一个Compiled对象。对返回值调用str()unicode()将产生结果的字符串表示。Compiled对象还可以使用params访问器返回绑定参数名称和值的字典。

参数:

  • bind – 一个ConnectionEngine,可以提供一个Dialect以生成一个Compiled对象。如果binddialect参数都被省略,则使用默认的 SQL 编译器。
  • column_keys – 用于 INSERT 和 UPDATE 语句,一个列名列表,应该出现在编译语句的 VALUES 子句中。如果为None,则渲染来自目标表对象的所有列。
  • dialect – 一个Dialect实例,可以生成一个Compiled对象。此参数优先于bind参数。
  • compile_kwargs
    可选的附加参数字典,将传递给所有“visit”方法中的编译器。这允许将任何自定义标志传递给自定义编译结构,例如。它也用于通过传递literal_binds标志的情况:
from sqlalchemy.sql import table, column, select
t = table('t', column('x'))
s = select(t).where(t.c.x == 5)
print(s.compile(compile_kwargs={"literal_binds": True}))

另请参阅

如何将 SQL 表达式渲染为字符串,可能包含内联的绑定参数?

method corresponding_column(column: KeyedColumnElement[Any], require_embedded: bool = False) → KeyedColumnElement[Any] | None

Selectable.corresponding_column() 方法继承 Selectable

给定一个ColumnElement,从此SelectableSelectable.exported_columns集合中返回导出的ColumnElement对象,该对象对应于通过公共祖先列对应于该原始ColumnElement

参数:

  • column – 要匹配的目标ColumnElement
  • require_embedded – 仅返回给定ColumnElement的相应列,如果给定的ColumnElement实际上存在于此Selectable的子元素中。通常,如果列仅与此Selectable的导出列之一共享共同的祖先,则列将匹配。

另请参阅

Selectable.exported_columns - 用于操作的ColumnCollection

ColumnCollection.corresponding_column() - 实现方法。

method delete() → Delete

生成针对此TableClausedelete()构造。

例如:

table.delete().where(table.c.id==7)

查看delete()以获取参数和用法信息。

attribute description
attribute entity_namespace

继承自 FromClause.entity_namespace 属性的 FromClause

返回用于在 SQL 表达式中进行基于名称访问的命名空间。

这是用于解析“filter_by()”类型表达式的命名空间,例如:

stmt.filter_by(address='some address')

默认为.c集合,但在内部可以使用“entity_namespace”注释进行覆盖以提供替代结果。

attribute exported_columns

继承自 FromClause.exported_columns 属性的 FromClause

代表此Selectable的“导出”列的ColumnCollection

FromClause对象的“导出”列与FromClause.columns集合是同义词。

版本 1.4 中的新功能。

另请参阅

Selectable.exported_columns

SelectBase.exported_columns

attribute foreign_keys

继承自 FromClause.foreign_keys 属性的 FromClause

返回此 FromClause 引用的ForeignKey标记对象的集合。

每个ForeignKey都是Table范围内的一个ForeignKeyConstraint的成员。

另请参阅

Table.foreign_key_constraints

method get_children(*, omit_attrs: Tuple[str, ...] = (), **kw: Any) → Iterable[HasTraverseInternals]

继承自 HasTraverseInternals.get_children() 方法的 HasTraverseInternals

返回此HasTraverseInternals的直接子HasTraverseInternals元素。

用于访问遍历。

**kw 可能包含改变返回集合的标志,例如返回子项的子集以减少更大的遍历,或者从不同的上下文(例如模式级别的集合而不是子句级别)返回子项。

attribute implicit_returning = False

TableClause不支持具有主键或列级默认值,因此隐式返回不适用。

attribute inherit_cache: bool | None = None

继承自 HasCacheKey.inherit_cache 属性的 HasCacheKey

指示此HasCacheKey实例是否应使用其直接超类使用的缓存键生成方案。

该属性默认为None,表示构造尚未考虑其是否适合参与缓存;这在功能上等效于将值设置为False,除了还会发出警告。

如果对象对应的 SQL 不会根据本类本地属性而变化,并且不是其超类,则可以在特定类上设置此标志为True

另请参阅

为自定义构造启用缓存支持 - 设置第三方或用户定义的 SQL 构造的 HasCacheKey.inherit_cache 属性的一般指南。

method insert() → Insert

生成一个针对这个TableClauseInsert 构造。

例如:

table.insert().values(name='foo')

有关参数和用法信息,请参阅 insert()

method is_derived_from(fromclause: FromClause | None) → bool

继承自 FromClause.is_derived_from() 方法于 FromClause

如果这个FromClause是从给定的FromClause‘派生’,则返回True

一个示例是表的别名是从该表派生的。

method join(right: _FromClauseArgument, onclause: _ColumnExpressionArgument[bool] | None = None, isouter: bool = False, full: bool = False) → Join

继承自 FromClause.join() 方法于 FromClause

从这个FromClause返回一个Join到另一个FromClause

例如:

from sqlalchemy import join
j = user_table.join(address_table,
                user_table.c.id == address_table.c.user_id)
stmt = select(user_table).select_from(j)

会发出类似以下的 SQL 语句:

SELECT user.id, user.name FROM user
JOIN address ON user.id = address.user_id

参数:

  • right – 连接的右侧;这是任何 FromClause 对象,比如一个 Table 对象,也可以是一个可选择的兼容对象,比如一个 ORM 映射类。
  • onclause – 表示连接的 ON 子句的 SQL 表达式。如果保留为 NoneFromClause.join() 将尝试基于外键关系连接两个表。
  • isouter – 如果为 True,则渲染一个 LEFT OUTER JOIN,而不是 JOIN。
  • full – 如果为 True,则渲染一个 FULL OUTER JOIN,而不是 LEFT OUTER JOIN。暗示 FromClause.join.isouter

另见

join() - 独立的函数

Join - 生成对象的类型

method lateral(name: str | None = None) → LateralFromClause

继承自 SelectableSelectable.lateral() 方法

返回此 Selectable 的 LATERAL 别名。

返回值是顶层 lateral() 函数提供的 Lateral 构造。

另请参见

LATERAL 关联 - 用法概述。

method outerjoin(right: _FromClauseArgument, onclause: _ColumnExpressionArgument[bool] | None = None, full: bool = False) → Join

继承自 FromClauseFromClause.outerjoin() 方法

返回一个从此 FromClause 到另一个 FromClauseJoin,并将“isouter”标志设置为 True。


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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(3)
SqlAlchemy 2.0 中文文档(二十九)
36 4
|
3月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(2)
SqlAlchemy 2.0 中文文档(二十九)
34 7
|
3月前
|
SQL 缓存 关系型数据库
SqlAlchemy 2.0 中文文档(三十五)(2)
SqlAlchemy 2.0 中文文档(三十五)
35 2
|
3月前
|
SQL 缓存 关系型数据库
SqlAlchemy 2.0 中文文档(三十五)(4)
SqlAlchemy 2.0 中文文档(三十五)
25 1
|
3月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(三十五)(1)
SqlAlchemy 2.0 中文文档(三十五)
45 1
|
3月前
|
SQL 存储 关系型数据库
SqlAlchemy 2.0 中文文档(二十九)(1)
SqlAlchemy 2.0 中文文档(二十九)
41 4
|
3月前
|
SQL 存储 关系型数据库
SqlAlchemy 2.0 中文文档(三十四)(4)
SqlAlchemy 2.0 中文文档(三十四)
37 1
|
3月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(三十四)(5)
SqlAlchemy 2.0 中文文档(三十四)
35 0
|
3月前
|
存储 SQL 测试技术
SqlAlchemy 2.0 中文文档(三十一)(1)
SqlAlchemy 2.0 中文文档(三十一)
30 1
|
3月前
|
SQL 数据库 Python
SqlAlchemy 2.0 中文文档(三十一)(3)
SqlAlchemy 2.0 中文文档(三十一)
23 1