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

相关文章
|
2天前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(3)
SqlAlchemy 2.0 中文文档(二十九)
16 4
|
2天前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(2)
SqlAlchemy 2.0 中文文档(二十九)
20 7
|
3天前
|
SQL 存储 关系型数据库
SqlAlchemy 2.0 中文文档(二十九)(1)
SqlAlchemy 2.0 中文文档(二十九)
16 4
|
2天前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(4)
SqlAlchemy 2.0 中文文档(二十九)
16 4
|
2天前
|
SQL 缓存 前端开发
SqlAlchemy 2.0 中文文档(二十七)(5)
SqlAlchemy 2.0 中文文档(二十七)
10 2
|
2天前
|
SQL 前端开发 关系型数据库
SqlAlchemy 2.0 中文文档(二十七)(2)
SqlAlchemy 2.0 中文文档(二十七)
14 2
|
3天前
|
SQL 缓存 API
SqlAlchemy 2.0 中文文档(二十)(5)
SqlAlchemy 2.0 中文文档(二十)
9 1
|
3天前
|
SQL 存储 测试技术
SqlAlchemy 2.0 中文文档(二十)(3)
SqlAlchemy 2.0 中文文档(二十)
10 1
|
3天前
|
SQL 测试技术 API
SqlAlchemy 2.0 中文文档(二十)(4)
SqlAlchemy 2.0 中文文档(二十)
10 1
|
2天前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(5)
SqlAlchemy 2.0 中文文档(二十九)
11 1