SqlAlchemy 2.0 中文文档(二十一)(1)

简介: SqlAlchemy 2.0 中文文档(二十一)


原文:docs.sqlalchemy.org/en/20/contents.html

传统查询 API

原文:docs.sqlalchemy.org/en/20/orm/queryguide/query.html

关于传统查询 API

本页包含了由 Python 生成的Query构造的文档,多年来这是与 SQLAlchemy ORM 一起使用时的唯一 SQL 接口。从版本 2.0 开始,现在采用的是全新的工作方式,其中与 Core 相同的select()构造对 ORM 同样有效,为构建查询提供了一致的接口。

对于在 SQLAlchemy 2.0 API 之前构建的任何应用程序,Query API 通常表示应用程序中绝大多数数据库访问代码,并且大部分Query API 不会从 SQLAlchemy 中删除。在执行Query对象时,Query对象在幕后现在会将自己转换为 2.0 样式的select()对象,因此现在它只是一个非常薄的适配器 API。

要了解如何将基于Query的应用程序迁移到 2.0 样式,请参阅 2.0 迁移 - ORM 用法。

要了解如何以 2.0 样式编写 ORM 对象的 SQL,请从 SQLAlchemy 统一教程开始。2.0 样式查询的其他参考资料请参阅 ORM 查询指南。

查询对象

Query是根据给定的Session产生的,使用Session.query()方法:

q = session.query(SomeMappedClass)

以下是Query对象的完整接口。

对象名称 描述
查询 ORM 级别的 SQL 构造对象。
class sqlalchemy.orm.Query

ORM 级别的 SQL 构造对象。

传统特性

ORM Query对象是 SQLAlchemy 2.0 的传统构造。请参阅传统查询 API 顶部的注释,其中包括迁移文档的链接。

查询 对象通常最初是使用 Session.query() 方法生成的,Session 的情况比较少是直接实例化 Query 并使用 Query.with_session() 方法与 Session 关联。

成员

init(), add_column(), add_columns(), add_entity(),  all(), apply_labels(), as_scalar(), autoflush(), column_descriptions,  correlate(), count(), cte(), delete(), distinct(), enable_assertions(),  enable_eagerloads(), except_(), except_all(), execution_options(),  exists(), filter(), filter_by(), first(), from_statement(), get(),  get_children(), get_execution_options(), get_label_style, group_by(),  having(), instances(), intersect(), intersect_all(), is_single_entity,  join(), label(), lazy_loaded_from, limit(), merge_result(), offset(),  one(), one_or_none(), only_return_tuples(), options(), order_by(),  outerjoin(), params(), populate_existing(), prefix_with(),  reset_joinpoint(), scalar(), scalar_subquery(), select_from(),  selectable, set_label_style(), slice(), statement, subquery(),  suffix_with(), tuples(), union(), union_all(), update(), value(),  values(), where(), whereclause, with_entities(), with_for_update(),  with_hint(), with_labels(), with_parent(), with_session(),  with_statement_hint(), with_transformation(), yield_per()

类签名

sqlalchemy.orm.Querysqlalchemy.sql.expression._SelectFromElementssqlalchemy.sql.annotation.SupportsCloneAnnotationssqlalchemy.sql.expression.HasPrefixessqlalchemy.sql.expression.HasSuffixessqlalchemy.sql.expression.HasHintssqlalchemy.event.registry.EventTargetsqlalchemy.log.Identifiedsqlalchemy.sql.expression.Generativesqlalchemy.sql.expression.Executabletyping.Generic

method __init__(entities: _ColumnsClauseArgument[Any] | Sequence[_ColumnsClauseArgument[Any]], session: Session | None = None)

直接构造一个Query

例如:

q = Query([User, Address], session=some_session)

以上等价于:

q = some_session.query(User, Address)

参数:

  • entities – 一个实体和/或 SQL 表达式的序列。
  • session – 与Query将关联的Session。可选;也可以通过Query.with_session()方法将QuerySession关联。

另请参见

Session.query()

Query.with_session()

method add_column(column: _ColumnExpressionArgument[Any]) → Query[Any]

将列表达式添加到要返回的结果列列表中。

自版本 1.4 起已弃用:Query.add_column()已弃用,并将在将来的版本中删除。请使用 Query.add_columns()

method add_columns(*column: _ColumnExpressionArgument[Any]) → Query[Any]

将一个或多个列表达式添加到要返回的结果列列表中。

另请参见

Select.add_columns() - v2 可比较的方法。

method add_entity(entity: _EntityType[Any], alias: Alias | Subquery | None = None) → Query[Any]

将映射实体添加到要返回的结果列列表中。

另请参见

Select.add_columns() - v2 可比较的方法。

method all() → List[_T]

将由此Query表示的结果返回为列表。

这将导致底层 SQL 语句的执行。

警告

当要求 Query 对象返回由完整的 ORM 映射实体组成的序列或迭代器时,将根据主键对条目进行去重。有关更多详情,请参阅 FAQ。

另请参阅

我的查询返回的对象数量与 query.count() 告诉我的数量不一致 - 为什么?

另请参阅

Result.all() - v2 可比较方法。

Result.scalars() - v2 可比较方法。

method apply_labels() → Self

自版本 2.0 弃用:Query.with_labels()Query.apply_labels() 方法被视为 SQLAlchemy 1.x 系列的遗留构造,在 2.0 中成为遗留构造。请改用 set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)。 (有关 SQLAlchemy 2.0 的背景,请参阅:SQLAlchemy 2.0 - Major Migration Guide)

method as_scalar() → ScalarSelect[Any]

返回由此 Query 表示的完整 SELECT 语句,转换为标量子查询。

自版本 1.4 弃用:Query.as_scalar() 方法已弃用,并将在将来的版本中删除。请参考 Query.scalar_subquery()

method autoflush(setting: bool) → Self

返回具有特定“autoflush”设置的查询。

自 SQLAlchemy 1.4 起,Query.autoflush() 方法等效于在 ORM 级别使用 autoflush 执行选项。有关此选项的更多背景,请参阅 Autoflush 部分。

attribute column_descriptions

返回有关此 Query 将返回的列的元数据。

格式是一个字典列表:

user_alias = aliased(User, name='user2')
q = sess.query(User, User.id, user_alias)
# this expression:
q.column_descriptions
# would return:
[
 {
 'name':'User',
 'type':User,
 'aliased':False,
 'expr':User,
 'entity': User
 },
 {
 'name':'id',
 'type':Integer(),
 'aliased':False,
 'expr':User.id,
 'entity': User
 },
 {
 'name':'user2',
 'type':User,
 'aliased':True,
 'expr':user_alias,
 'entity': user_alias
 }
]

另请参阅

此 API 也可使用 2.0 风格 查询,文档位于:

  • 检查来自启用 ORM 的 SELECT 和 DML 语句的实体和列
  • Select.column_descriptions
method correlate(*fromclauses: Literal[None, False] | FromClauseRole | Type[Any] | Inspectable[_HasClauseElement[Any]] | _HasClauseElement[Any]) → Self

返回一个 Query 构造,将给定的 FROM 子句与封闭的 Queryselect() 关联起来。

此处的方法接受映射类、aliased() 构造和 Mapper 构造作为参数,这些参数会被解析为表达式构造,以及适当的表达式构造。

最终,相关参数将被强制转换为表达式构造,然后传递给 Select.correlate()

在这种情况下,相关参数会生效,例如在使用 Query.from_self() 时,或者在将由Query.subquery()返回的子查询嵌入到另一个select() 构造中时。

另请参阅

Select.correlate() - v2 等效方法。

method count() → int

返回此Query形成的 SQL 将返回的行数计数。

这将生成以下查询的 SQL 语句:

SELECT count(1) AS count_1 FROM (
 SELECT <rest of query follows...>
) AS anon_1

上述 SQL 返回一个单行,即 count 函数的聚合值;然后Query.count() 方法返回该单个整数值。

警告

需要注意的是,count() 返回的值并不等同于此 Query 通过 .all() 等方法返回的 ORM 对象数。当 Query 对象被要求返回完整实体时,将根据主键对条目进行重复消除,这意味着如果相同的主键值在结果中出现超过一次,则只会存在一个该主键的对象。这不适用于针对单个列的查询。

另请参阅

我的查询的返回对象数与 query.count() 告诉我的不一样 - 为什么?

对于对特定列进行精细控制的计数,跳过子查询的使用或以其他方式控制 FROM 子句,或使用其他聚合函数,可以结合使用expression.func表达式和 Session.query(),例如:

from sqlalchemy import func
# count User records, without
# using a subquery.
session.query(func.count(User.id))
# return count of user "id" grouped
# by "name"
session.query(func.count(User.id)).\
 group_by(User.name)
from sqlalchemy import distinct
# count distinct "name" values
session.query(func.count(distinct(User.name)))

另请参阅

2.0 迁移 - ORM 用法

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

返回由此Query表示的完整 SELECT 语句,表示为公共表达式(CTE)。

参数和用法与 SelectBase.cte() 方法相同;有关更多详细信息,请参阅该方法。

这里是 PostgreSQL WITH RECURSIVE 示例。请注意,在此示例中,included_parts cte 和其 incl_alias 别名是核心可选择的,这意味着可以通过 .c. 属性访问列。parts_alias 对象是 Part 实体的 aliased() 实例,因此可以直接访问列映射属性:

from sqlalchemy.orm import aliased
class Part(Base):
 __tablename__ = 'part'
 part = Column(String, primary_key=True)
 sub_part = Column(String, primary_key=True)
 quantity = Column(Integer)
included_parts = session.query(
 Part.sub_part,
 Part.part,
 Part.quantity).\
 filter(Part.part=="our part").\
 cte(name="included_parts", recursive=True)
incl_alias = aliased(included_parts, name="pr")
parts_alias = aliased(Part, name="p")
included_parts = included_parts.union_all(
 session.query(
 parts_alias.sub_part,
 parts_alias.part,
 parts_alias.quantity).\
 filter(parts_alias.part==incl_alias.c.sub_part)
 )
q = session.query(
 included_parts.c.sub_part,
 func.sum(included_parts.c.quantity).
 label('total_quantity')
 ).\
 group_by(included_parts.c.sub_part)

请参阅

Select.cte() - v2 等效方法。

method delete(synchronize_session: SynchronizeSessionArgument = 'auto') → int

使用任意 WHERE 子句执行 DELETE。

从数据库中删除与此查询匹配的行。

例如:

sess.query(User).filter(User.age == 25).\
 delete(synchronize_session=False)
sess.query(User).filter(User.age == 25).\
 delete(synchronize_session='evaluate')

警告

请参阅 ORM-Enabled INSERT、UPDATE 和 DELETE 语句 章节以了解重要的注意事项和警告,包括在使用映射器继承配置时批量 UPDATE 和 DELETE 的限制。

参数:

synchronize_session – 选择在会话中更新对象属性的策略。请参阅 ORM-Enabled INSERT、UPDATE 和 DELETE 语句 章节讨论这些策略。

返回:

数据库的“行计数”功能返回的匹配行数。

请参阅

ORM-Enabled INSERT、UPDATE 和 DELETE 语句

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

对查询应用 DISTINCT 并返回新生成的 Query

注意

ORM 级别的 distinct() 调用包含逻辑,将自动将查询的 ORDER BY 中的列添加到 SELECT 语句的列子句中,以满足数据库后端的常见需求,即在使用 DISTINCT 时,ORDER BY 列应作为 SELECT 列的一部分。然而,这些列 不会 添加到实际由 Query 获取的列列表中,因此不会影响结果。然而,在使用 Query.statement 访问器时,这些列会通过。

自版本 2.0 起已弃用:此逻辑已弃用,将在 SQLAlchemy 2.0 中删除。请参阅 使用 DISTINCT 与其他列,但仅选择实体 了解 2.0 中此用例的描述。

请参阅

Select.distinct() - v2 等效方法。

参数:

*expr

可选的列表达式。当存在时,PostgreSQL 方言将呈现 DISTINCT ON () 结构。

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

method enable_assertions(value: bool) → Self

控制是否生成断言。

当设置为 False 时,返回的 Query 在某些操作之前不会断言其状态,包括调用 filter() 时未应用  LIMIT/OFFSET,调用 get() 时不存在条件,以及调用 filter()/order_by()/group_by()  等时不存在“from_statement()”。此更宽松的模式由自定义的 Query 子类使用,以指定标准或其他修改器在通常的使用模式之外。

应注意确保使用模式是可行的。例如,由 from_statement()应用的语句将覆盖由 filter()或 order_by()设置的任何条件。

method enable_eagerloads(value: bool) → Self

控制是否呈现急切连接和子查询。

当设置为 False 时,返回的 Query 将不会渲染急切连接,无论 joinedload()subqueryload() 选项或映射器级别的 lazy='joined'/lazy='subquery' 配置如何。

当将 Query 的语句嵌套到子查询或其他可选择项中时,或者当使用Query.yield_per()时主要用于。

method except_(*q: Query) → Self

生成此 Query 对一项或多项查询的 EXCEPT。

Query.union()的工作方式相同。请参阅该方法以获取用法示例。

另请参阅

Select.except_() - v2 等效方法。

method except_all(*q: Query) → Self

生成此 Query 对一项或多项查询的 EXCEPT ALL。

Query.union()的工作方式相同。请参阅该方法以获取用法示例。

另请参阅

Select.except_all() - v2 等效方法。

method execution_options(**kwargs: Any) → Self

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

此处允许的选项包括所有被Connection.execution_options()接受的选项,以及一系列 ORM 特定选项:

populate_existing=True - 等效于使用Query.populate_existing()

autoflush=True|False - 等效于使用Query.autoflush()

yield_per= - 等效于使用Query.yield_per()

注意,如果使用了Query.yield_per()方法或执行选项,则stream_results执行选项会自动启用。

版本 1.4 中的新功能:- 添加了 ORM 选项到Query.execution_options()

在使用 2.0 风格查询时,执行选项也可以在每次执行时指定,通过Session.execution_options参数。

警告

Connection.execution_options.stream_results参数不应在单个 ORM 语句执行的级别使用,因为Session不会跟踪来自不同模式转换映射的对象在单个会话中。对于单个Session范围内的多个模式转换映射,请参见水平分片。

另请参阅

使用服务器端游标(又名流式结果)

Query.get_execution_options()

Select.execution_options() - v2 等效方法。

method exists() → Exists

一个方便的方法,将查询转换为形式为 EXISTS(SELECT 1 FROM … WHERE …)的 EXISTS 子查询。

例如:

q = session.query(User).filter(User.name == 'fred')
session.query(q.exists())

生成类似于:

SELECT EXISTS (
 SELECT 1 FROM users WHERE users.name = :name_1
) AS anon_1

EXISTS 构造通常用于 WHERE 子句中:

session.query(User.id).filter(q.exists()).scalar()

请注意,某些数据库(如 SQL Server)不允许在 SELECT 的列子句中存在 EXISTS 表达式。要基于存在性选择简单的布尔值作为 WHERE,使用literal()

from sqlalchemy import literal
session.query(literal(True)).filter(q.exists()).scalar()

另请参阅

Select.exists() - v2 可比较的方法。

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

将给定的过滤条件应用于此Query的副本,使用 SQL 表达式。

例如:

session.query(MyClass).filter(MyClass.name == 'some name')

多个条件可以以逗号分隔的方式指定;效果是它们将使用and_()函数连接在一起:

session.query(MyClass).\
 filter(MyClass.name == 'some name', MyClass.id > 5)

条件是适用于 select 的 WHERE 子句的任何 SQL 表达式对象。字符串表达式通过text()构造被强制转换为 SQL 表达式构造。

另请参阅

Query.filter_by() - 根据关键字表达式进行过滤。

Select.where() - v2 等效方法。

method filter_by(**kwargs: Any) → Self

将给定的过滤条件应用于此Query的副本,使用关键字表达式。

例如:

session.query(MyClass).filter_by(name = 'some name')

可以指定多个条件,以逗号分隔;其效果是它们将使用and_()函数连接在一起:

session.query(MyClass).\
 filter_by(name = 'some name', id = 5)

关键字表达式是从查询的主要实体或最后一个曾被调用过Query.join()的目标实体中提取的。

另请参阅

Query.filter() - 根据 SQL 表达式进行过滤。

Select.filter_by() - v2 可比较的方法。

method first() → _T | None

返回此Query的第一个结果,如果结果不包含任何行,则返回 None。

first()在生成的 SQL 中应用了一个限制为 1,因此仅在服务器端生成一个主要实体行(请注意,如果存在联接加载的集合,则可能由多个结果行组成)。

调用Query.first()会导致基础查询的执行。

另请参阅

Query.one()

Query.one_or_none()

Result.first() - v2 可比较的方法。

Result.scalars() - v2 可比较的方法。

method from_statement(statement: ExecutableReturnsRows) → Self

执行给定的 SELECT 语句并返回结果。

此方法绕过所有内部语句编译,并且语句在不修改的情况下执行。

该语句通常是一个text()select()结构,应返回与此Query所代表的实体类相对应的列集。

另请参阅

Select.from_statement() - v2 可比较的方法。

method get(ident: _PKIdentityArgument) → Any | None

根据给定的主键标识符返回一个实例,如果找不到则返回None

自版本 2.0 起已弃用:Query.get() 方法被认为是 SQLAlchemy 1.x 系列的遗留部分,并且在 2.0 中成为遗留构造。该方法现在可用作 Session.get()(关于 SQLAlchemy 2.0 的背景信息,请参阅:SQLAlchemy 2.0 - 主要迁移指南)

例如:

my_user = session.query(User).get(5)
some_object = session.query(VersionedFoo).get((5, 10))
some_object = session.query(VersionedFoo).get(
 {"id": 5, "version_id": 10})

Query.get() 特殊之处在于它提供对所属 Session 的标识映射的直接访问。如果给定的主键标识符存在于本地标识映射中,则对象将直接从此集合返回,而不会发出任何 SQL,除非对象已被标记为完全过期。如果不存在,则执行 SELECT 来定位对象。

Query.get() 会检查对象是否存在于标识映射中并标记为过期 - 会发出一个 SELECT 来刷新对象并确保行仍然存在。如果不存在,则会引发 ObjectDeletedError

Query.get() 仅用于返回单个映射实例,而不是多个实例或单个列构造,并且严格限于单个主键值。源 Query 必须以这种方式构造,即针对单个映射实体,没有额外的过滤条件。可以通过 Query.options() 应用加载选项,如果对象尚未在本地存在,则将使用该选项。


SqlAlchemy 2.0 中文文档(二十一)(2)https://developer.aliyun.com/article/1560617

相关文章
|
消息中间件 存储 运维
浅析阿里《云原生架构白皮书》
提前看了《云原生架构白皮书》一直想着要写点东西,拖延来去[《白皮书》](https://developer.aliyun.com/topic/cn-architecture-paper)已经正式发布2天了,我还迟迟没有动手。没动手的一方面原因是我的懒癌症又犯了;另一个原因是《白皮书》覆盖面之广,基本触及到云原生的方方面面,而我在云原生方面的知识储备不足以支撑我写出一篇好文。
6186 0
浅析阿里《云原生架构白皮书》
|
域名解析 Cloud Native jenkins
【Drone+Gitlab】一条龙服务,直接起飞 — 从介绍->部署->配置->写.drone.yml流水线+常见的报错解决
gitlab+drone部署安装,编写.drone.yml流水线 drone是一个持续集成化工具,gitlab是一个代码仓库,.drone.yml流水线编写 fatal: unable to access,could not resolve host 克隆地址连接不上(修改默认clone克隆),没有Trusted选项,启动drone-server时添加(--env=DRONE_USER_CREATE=username:root,admin:true) .drone.yml文件中sed命令报错
2628 0
【Drone+Gitlab】一条龙服务,直接起飞 — 从介绍->部署->配置->写.drone.yml流水线+常见的报错解决
|
8月前
|
人工智能 安全 网络安全
Burp Suite Professional 2025.5 for macOS x64 & ARM64 - 领先的 Web 渗透测试软件
Burp Suite Professional 2025.5 for macOS x64 & ARM64 - 领先的 Web 渗透测试软件
384 3
|
3月前
|
JSON NoSQL Redis
企业微信iPad协议:事件流逆向与轻量级网关实现
本文提出基于企业微信iPad协议的轻量级网关,通过长连接实现毫秒级事件推送,支持成员撤回、删除等细粒度事件捕获。采用Go解析protobuf事件流,Redis幂等去重,MQTT+JSON输出,兼容审计与风控,单实例承载600+账号,P99延迟18ms,无缝接入微服务。
204 0
|
9月前
|
数据可视化 搜索推荐
Ollama-Deep-Researcher-本地Mac结合魔搭社区模型搭建网页研究助手
Ollama Deep Researcher 是一款完全本地化的网络研究助手,可使用Ollama托管的任何 LLM 。输入一个主题,它将生成网络搜索查询,收集网络搜索结果(默认通过Tavily),总结网络搜索结果,反思总结以检查知识差距,生成新的搜索查询以解决差距,搜索并改进总结,循环次数由用户定义。它将为用户提供最终的 markdown 摘要,其中包含所有使用的来源。
401 2
|
测试技术 数据库 Python
SQLAlchemy的同步和异步的代码对比
这篇文章比较了SQLAlchemy同步和异步操作的代码差异,包括创建数据库引擎、会话、执行查询、新增、编辑和删除数据的不同方式。
678 7
|
SQL 缓存 API
SqlAlchemy 2.0 中文文档(二十八)(4)
SqlAlchemy 2.0 中文文档(二十八)
538 1
|
监控 前端开发 UED
理解 MVVM 中的数据双向绑定
【10月更文挑战第21天】数据双向绑定是 MVVM 架构中的一个核心特性,它为前端开发带来了诸多便利和优势。理解并熟练运用数据双向绑定,有助于我们构建更加高效、交互性更强的应用程序。同时,我们也需要在实际应用中注意性能和复杂性等方面的问题,以确保应用的良好运行和用户体验。还可以结合具体的项目经验和实际案例,进一步深入探讨数据双向绑定在不同场景下的应用和优化策略。
|
前端开发 JavaScript Java
谷粒商城笔记+踩坑(3)——商品服务-三级分类、网关跨域
商品服务-三级分类增删改查、跨域问题、逻辑删除
|
存储 Java API
Android期末项目 新闻APP的设计与实现(一)
Android期末项目 新闻APP的设计与实现
711 0

热门文章

最新文章