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_options
和Session.execute.execution_options
。
与其他类型的选项(如 ORM 加载程序选项)相比,执行选项的主要特征是执行选项从不影响查询的编译 SQL,只影响 SQL 语句本身如何调用或结果如何获取。也就是说,执行选项不是 SQL 编译所能容纳的内容,它们也不被认为是语句的缓存状态的一部分。
Executable.execution_options()
方法是生成的,就像应用于Engine
和Query
对象的方法一样,这意味着当调用该方法时,将返回对象的副本,该副本应用给定的参数,但原始对象保持不变:
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_options
或ORMExecuteState.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
为连接或一类连接设置隔离级别。此选项仅被Connection
或Engine
接受。Connection.execution_options.stream_results
- 表示结果应该使用服务器端游标获取;此选项可被Connection
、Connection.execute.execution_options
参数上的Connection.execute()
以及Executable.execution_options()
在 SQL 语句对象上接受,同样也被 ORM 构造如Session.execute()
接受。Connection.execution_options.compiled_cache
- 表示将作为Connection
或Engine
的 SQL 编译缓存的字典,同样也适用于 ORM 方法如Session.execute()
。可以传递None
来禁用语句的缓存。此选项不被Executable.execution_options()
接受,因为在语句对象中携带编译缓存是不明智的。Connection.execution_options.schema_translate_map
- 由模式翻译映射功能使用的模式名称映射,被Connection
、Engine
、Executable
接受,同样也被 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()
方法建模的,以支持使用具有 Session
的 Select
对象可用的 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()
方法的行为,以支持通过使用带有 Session
的 Select
对象来使 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
将是一个包含col1
和col2
对象的集合。对于针对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_ONLY
、SelectLabelStyle.LABEL_STYLE_TABLENAME_PLUS_COL
和 SelectLabelStyle.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
参数的 Table
或 Alias
。方言实现通常使用 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 语句的基类。
这包括Select
、CompoundSelect
和TextualSelect
。
成员
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.c
和 SelectBase.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
, 和 TextualSelect
的 SelectBase
子类上调用 SelectBase.subquery()
方法或为方便起见调用 SelectBase.alias()
方法来创建 Subquery
。在 FROM 子句中表示 SELECT 语句的主体部分,后面跟着通常的“AS ”,定义了所有“别名”对象。
Subquery
对象与 Alias
对象非常相似,并且可以以等效的方式使用。Alias
和 Subquery
之间的区别在于 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
对象的命名集合。
columns
或c
集合是使用绑定到表或其他可选择列构建 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
– 一个Connection
或Engine
,可以提供一个Dialect
以生成一个Compiled
对象。如果bind
和dialect
参数都被省略,则使用默认的 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
,从此Selectable
的Selectable.exported_columns
集合中返回导出的ColumnElement
对象,该对象对应于通过公共祖先列对应于该原始ColumnElement
。
参数:
column
– 要匹配的目标ColumnElement
。require_embedded
– 仅返回给定ColumnElement
的相应列,如果给定的ColumnElement
实际上存在于此Selectable
的子元素中。通常,如果列仅与此Selectable
的导出列之一共享共同的祖先,则列将匹配。
另请参阅
Selectable.exported_columns
- 用于操作的ColumnCollection
。
ColumnCollection.corresponding_column()
- 实现方法。
method delete() → Delete
生成针对此TableClause
的delete()
构造。
例如:
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
生成一个针对这个TableClause
的 Insert
构造。
例如:
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 表达式。如果保留为None
,FromClause.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
继承自 Selectable
的 Selectable.lateral()
方法
返回此 Selectable
的 LATERAL 别名。
返回值是顶层 lateral()
函数提供的 Lateral
构造。
另请参见
LATERAL 关联 - 用法概述。
method outerjoin(right: _FromClauseArgument, onclause: _ColumnExpressionArgument[bool] | None = None, full: bool = False) → Join
继承自 FromClause
的 FromClause.outerjoin()
方法
返回一个从此 FromClause
到另一个 FromClause
的 Join
,并将“isouter”标志设置为 True。
SqlAlchemy 2.0 中文文档(三十五)(4)https://developer.aliyun.com/article/1562894