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

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

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


参数:

ident

表示主键的标量、元组或字典。对于复合(例如,多列)主键,应传递元组或字典。

对于单列主键,标量调用形式通常最为便捷。如果一行的主键是值“5”,则调用如下所示:

my_object = query.get(5)

元组形式包含主键值,通常按照它们对应于映射的 Table 对象的主键列的顺序,或者如果使用了 Mapper.primary_key 配置参数,则按照该参数的使用顺序。例如,如果一行的主键由整数数字“5, 10”表示,则调用如下所示:

my_object = query.get((5, 10))

字典形式应该以键的形式包含对应于主键每个元素的映射属性名称。如果映射类具有 idversion_id 作为存储对象主键值的属性,则调用将如下所示:

my_object = query.get({"id": 5, "version_id": 10})

新版本 1.3 中的 Query.get() 方法现在可选择性地接受属性名到值的字典,以指示主键标识符。

返回:

对象实例,或 None

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

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

返回此 HasTraverseInternals 的即时子 HasTraverseInternals 元素。

这用于访问遍历。

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

method get_execution_options() → _ImmutableExecuteOptions

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

新版本 1.3 中新增。

另请参阅

Query.execution_options()

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

attribute get_label_style

检索当前的标签样式。

新版本 1.4 中新增。

另请参阅

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

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

将一个或多个 GROUP BY 准则应用于查询,并返回新生成的 Query

所有现有的 GROUP BY 设置都可以通过传递 None 来抑制 - 这将抑制任何配置在映射器上的 GROUP BY。

另请参阅

这些部分描述了 GROUP BY,是以 2.0 样式 调用的,但也适用于 Query

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

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

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

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

将 HAVING 准则应用于查询,并返回新生成的 Query

Query.having()Query.group_by() 结合使用。

HAVING 条件使得可以在聚合函数(如 COUNT、SUM、AVG、MAX 和 MIN)上使用过滤器,例如:

q = session.query(User.id).\
 join(User.addresses).\
 group_by(User.id).\
 having(func.count(Address.id) > 2)

另请参阅

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

method instances(result_proxy: CursorResult[Any], context: QueryContext | None = None) → Any

针对CursorResultQueryContext返回一个 ORM 结果。

自 2.0 版本起已弃用:Query.instances()方法已弃用,并将在将来的版本中移除。请改为使用 Select.from_statement()方法或与 Session.execute()结合使用 aliased()构造。

method intersect(*q: Query) → Self

对此查询与一个或多个查询进行 INTERSECT。

Query.union()的工作方式相同。参见该方法的使用示例。

另请参阅

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

method intersect_all(*q: Query) → Self

对此查询与一个或多个查询进行 INTERSECT ALL。

Query.union()的工作方式相同。参见该方法的使用示例。

另请参阅

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

attribute is_single_entity

指示此Query是否返回元组或单个实体。

如果此查询对其结果列表中的每个实例返回单个实体,则返回 True,如果此查询对其结果返回实体的元组,则返回 False。

从版本 1.3.11 开始的新功能。

另请参阅

Query.only_return_tuples()

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

创建针对此Query对象的标准的 SQL JOIN,并应用生成性地返回新生成的Query

简单关系连接

考虑两个类UserAddress之间的映射,其中存在一个关系User.addresses表示与每个User关联的Address对象的集合。Query.join()的最常见用法是沿着这个关系创建一个 JOIN,使用User.addresses属性作为指示器指示应该如何发生:

q = session.query(User).join(User.addresses)

在上面的情况下,调用Query.join()沿着User.addresses将导致大致等同于以下 SQL 的结果:

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

在上述示例中,我们将User.addresses称为传递给Query.join()的“on clause”,即,它指示如何构造 JOIN 的“ON”部分。

要构建连接的链,可以使用多个Query.join()调用。关联绑定属性一次暗示了连接的左侧和右侧:

q = session.query(User).\
 join(User.orders).\
 join(Order.items).\
 join(Item.keywords)

注意

如上例所示,调用 join()方法的顺序很重要。例如,如果我们在连接链中依次指定UserItemOrder,则 Query 将不知道如何正确连接;在这种情况下,根据传递的参数,它可能会引发一个不知道如何连接的错误,或者可能会产生无效的 SQL,数据库会因此而引发错误。在正确的实践中,应以使 JOIN 子句在 SQL 中呈现的方式调用Query.join()方法,并且每个调用应表示与之前内容的清晰链接。

连接到目标实体或可选择项

第二种形式的Query.join()允许将任何映射实体或核心可选择构造作为目标。在此用法中,Query.join()将尝试沿着两个实体之间的自然外键关系创建一个 JOIN:

q = session.query(User).join(Address)

在上述调用形式中,Query.join()会自动为我们创建“on 子句”。如果两个实体之间没有外键,或者如果目标实体与已在左侧的实体之间存在多个外键链接,从而创建连接需要更多信息,则此调用形式最终会引发错误。请注意,当指示连接到一个没有 ON 子句的目标时,不会考虑 ORM 配置的关系。

连接到具有 ON 子句的目标

第三种调用形式允许显式传递目标实体以及 ON 子句。一个包含 SQL 表达式作为 ON 子句的示例如下:

q = session.query(User).join(Address, User.id==Address.user_id)

上述形式也可以使用一个关联绑定属性作为 ON 子句:

q = session.query(User).join(Address, User.addresses)

上述语法对于希望连接到特定目标实体的别名的情况很有用。如果我们想要两次连接到Address,可以使用aliased()函数设置两个别名:

a1 = aliased(Address)
a2 = aliased(Address)
q = session.query(User).\
 join(a1, User.addresses).\
 join(a2, User.addresses).\
 filter(a1.email_address=='ed@foo.com').\
 filter(a2.email_address=='ed@bar.com')

使用关联绑定调用形式还可以使用PropComparator.of_type()方法指定目标实体;与上面的查询等效的查询如下:

a1 = aliased(Address)
a2 = aliased(Address)
q = session.query(User).\
 join(User.addresses.of_type(a1)).\
 join(User.addresses.of_type(a2)).\
 filter(a1.email_address == 'ed@foo.com').\
 filter(a2.email_address == 'ed@bar.com')

增强内置 ON 子句

作为为现有关系提供完整自定义 ON 条件的替代方法,可以将PropComparator.and_()函数应用于关系属性,以将额外条件增加到 ON 子句中;附加条件将使用 AND 与默认条件组合:

q = session.query(User).join(
 User.addresses.and_(Address.email_address != 'foo@bar.com')
)

版本 1.4 中的新功能。

连接到表和子查询

加入的目标也可以是任何表或 SELECT 语句,它可能与目标实体相关或不相关。使用适当的.subquery()方法以将查询转换为子查询:

subq = session.query(Address).\
 filter(Address.email_address == 'ed@foo.com').\
 subquery()
q = session.query(User).join(
 subq, User.id == subq.c.user_id
)

通过使用aliased()将子查询链接到实体,可以以特定关系和/或目标实体的术语连接到子查询:

subq = session.query(Address).\
 filter(Address.email_address == 'ed@foo.com').\
 subquery()
address_subq = aliased(Address, subq)
q = session.query(User).join(
 User.addresses.of_type(address_subq)
)

控制从何处连接

在当前Query状态的左侧与我们要连接的内容不一致的情况下,可以使用Query.select_from()方法:

q = session.query(Address).select_from(User).\
 join(User.addresses).\
 filter(User.name == 'ed')

这将生成类似于以下 SQL:

SELECT address.* FROM user
 JOIN address ON user.id=address.user_id
 WHERE user.name = :name_1

另请参阅

Select.join() - v2 相当的方法。

参数:

  • *props – 用于Query.join()的传入参数,现代用法中的 props 集合应视为一种或两种参数形式,即作为单个“目标”实体或 ORM 属性绑定关系,或作为目标实体加上一个“on clause”,该“on clause”可以是 SQL 表达式或 ORM 属性绑定关系。
  • isouter=False – 如果为 True,则使用的连接将是左外连接,就像调用了Query.outerjoin()方法一样。
  • full=False – 渲染 FULL OUTER JOIN;隐含isouter
method label(name: str | None) → Label[Any]

返回由此Query表示的完整 SELECT 语句,转换为具有给定名称标签的标量子查询。

另请参阅

Select.label() - v2 类似的方法。

attribute lazy_loaded_from

正在将此Query用于惰性加载操作的InstanceState

从版本 1.4 开始不推荐使用:此属性应通过ORMExecuteState.lazy_loaded_from属性查看,在SessionEvents.do_orm_execute()事件的上下文中。

另请参阅

ORMExecuteState.lazy_loaded_from

method limit(limit: _LimitOffsetType) → Self

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

另请参阅

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

method merge_result(iterator: FrozenResult[Any] | Iterable[Sequence[Any]] | Iterable[object], load: bool = True) → FrozenResult[Any] | Iterable[Any]

将结果合并到此 Query 对象的会话中。

自版本 2.0 弃用:Query.merge_result() 方法被视为 SQLAlchemy 1.x 系列的遗留构造,并在 2.0 中成为遗留构造。该方法已被 merge_frozen_result() 函数取代。 (有关 SQLAlchemy 2.0 的背景信息,请参阅:SQLAlchemy 2.0 - 主要迁移指南)

给定与此查询相同结构的 Query 返回的迭代器,返回一个相同的结果迭代器,所有映射实例都使用 Session.merge() 合并到会话中。 这是一种优化方法,将合并所有映射实例,保留结果行的结构和未映射列,比显式为每个值调用 Session.merge() 的方法开销小。

结果的结构是基于此 Query 的列列表确定的 - 如果这些列不对应,将会发生未经检查的错误。

‘load’ 参数与 Session.merge() 相同。

有关 Query.merge_result() 的用法示例,请参阅示例 Dogpile Caching 的源代码,其中 Query.merge_result() 用于有效地从缓存中恢复状态到目标 Session

method offset(offset: _LimitOffsetType) → Self

对查询应用 OFFSET ��返回新生成的 Query

另请参阅

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

method one() → _T

返回确切的一个结果或引发异常。

如果查询未选择任何行,则引发 sqlalchemy.orm.exc.NoResultFound。如果返回多个对象标识,或者对于仅返回标量值而不是完全映射实体的查询返回多行,则引发 sqlalchemy.orm.exc.MultipleResultsFound

调用one()会导致执行底层查询。

另请参见

Query.first()

Query.one_or_none()

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

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

method one_or_none() → _T | None

返回最多一个结果或引发异常。

如果查询未选择任何行,则返回None。 如果返回多个对象标识,或者如果对于返回标量值而不是完整标识映射的实体的查询返回多行,则引发sqlalchemy.orm.exc.MultipleResultsFound

调用Query.one_or_none()会导致执行底层查询。

另请参见

Query.first()

Query.one()

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

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

method only_return_tuples(value: bool) → Query

当设置为 True 时,查询结果将始终是一个Row对象。

这可以将通常返回单个实体作为标量的查询,在所有情况下返回一个Row结果。

另请参见

Query.tuples() - 返回元组,但在类型级别上也将结果类型化为Tuple

Query.is_single_entity()

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

method options(*args: ExecutableOption) → Self

返回一个新的Query对象,应用给定的映射器选项列表。

大多数提供的选项都涉及更改如何加载列和关系映射的属性。

另请参见

列加载选项

使用加载选项进行关系加载

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

应用一个或多个 ORDER BY 标准到查询,并返回新生成的Query

例如:

q = session.query(Entity).order_by(Entity.id, Entity.name)

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

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

另请参阅

这些部分描述了按 2.0 风格调用的 ORDER BY,但也适用于Query

ORDER BY - 在 SQLAlchemy 统一教程中

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

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

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

在此Query对象的条件上创建左外连接,并在生成式上应用,返回新生成的Query

使用方法与join()方法相同。

另请参阅

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

method params(_Query__params: Dict[str, Any] | None = None, **kw: Any) → Self

为可能已在 filter() 中指定的绑定参数添加值。

参数可以使用kwargs 指定,或者作为第一个位置参数使用单个字典。两者之所以都存在是因为kwargs 很方便,但是一些参数字典包含 Unicode 键,**kwargs 就不能用。

method populate_existing() → Self

返回一个将在加载时过期并刷新所有实例,或者从当前Session中重用的Query

从 SQLAlchemy 1.4 开始,Query.populate_existing()方法等效于在 ORM 级别使用populate_existing执行选项。有关此选项的更多背景信息,请参见 填充现有 部分。

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 构造,将在插入、更新或删除关键字之后呈现。
  • dialect – 可选的字符串方言名称,将仅限于将此前缀呈现为该方言。
method reset_joinpoint() → Self

返回一个新的 Query,其中“连接点”已被重置回查询的基本 FROM 实体。

该方法通常与 Query.join() 方法的 aliased=True 特性一起使用。请参阅 Query.join() 中的示例,了解其使用方法。

method scalar() → Any

返回第一个结果的第一个元素,如果没有行存在则返回 None。如果返回多行,则引发 MultipleResultsFound。

>>> session.query(Item).scalar()
<Item>
>>> session.query(Item.id).scalar()
1
>>> session.query(Item.id).filter(Item.id < 0).scalar()
None
>>> session.query(Item.id, Item.name).scalar()
1
>>> session.query(func.count(Parent.id)).scalar()
20

这将导致执行基础查询。

另请参阅

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

method scalar_subquery() → ScalarSelect[Any]

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

类似于 SelectBase.scalar_subquery()

自版本 1.4 起变更:Query.scalar_subquery() 方法取代了 Query.as_scalar() 方法。

另请参阅

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

method select_from(*from_obj: FromClauseRole | Type[Any] | Inspectable[_HasClauseElement[Any]] | _HasClauseElement[Any]) → Self

显式设置此 Query 的 FROM 子句。

Query.select_from() 常常与 Query.join() 结合使用,以控制从连接的“左”侧选择的实体。

此处的实体或可选择对象有效地替换了任何对 Query.join() 的调用的“左边缘”,当没有其他方式建立连接点时 - 通常,默认的“连接点”是查询对象的要选择的实体列表中最左边的实体。

一个典型的例子:

q = session.query(Address).select_from(User).\
 join(User.addresses).\
 filter(User.name == 'ed')

这将生成等效于以下 SQL:

SELECT address.* FROM user
JOIN address ON user.id=address.user_id
WHERE user.name = :name_1

参数:

*from_obj – 一个或多个要应用于 FROM 子句的实体集合。实体可以是映射类、AliasedClass对象、Mapper对象,以及核心FromClause元素,如子查询。

另请参阅

Query.join()

Query.select_entity_from()

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

attribute selectable

返回由此Query发出的Select对象。

用于inspect()兼容性,这相当于:

query.enable_eagerloads(False).with_labels().statement
method set_label_style(style: SelectLabelStyle) → Self

将列标签应用于 Query.statement 的返回值。

表示此查询的语句访问器应返回一个 SELECT 语句,该语句将标签应用于形式为_的所有列;这通常用于消除具有相同名称的多个表中的列的歧义。

当查询实际发出 SQL 以加载行时,它总是使用列标签。

注意

Query.set_label_style()方法应用于Query.statement的输出,应用于Query本身的任何结果行调用系统,例如Query.first()Query.all()等。要使用Query.set_label_style()执行查询,请使用Session.execute()调用Query.statement

result = session.execute(
 query
 .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
 .statement
)

1.4 版本中的新功能。

另请参阅

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

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

计算由给定索引表示的Query的“切片”,并返回结果Query

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

例如,

session.query(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)

另请参阅

Query.limit()

Query.offset()

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

attribute statement

由此 Query 表示的完整 SELECT 语句。

该语句默认情况下不会对构造应用歧义标签,除非首先调用 with_labels(True)。

method subquery(name: str | None = None, with_labels: bool = False, reduce_columns: bool = False) → Subquery

返回由此 Query 表示的完整 SELECT 语句,嵌入在一个 Alias 中。

查询中禁用了急切的 JOIN 生成。

另请参阅

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

参数:

  • name – 要分配为别名的字符串名称;这将传递给 FromClause.alias()。如果为 None,则在编译时将确定性地生成一个名称。
  • with_labels – 如果为 True,则首先将 with_labels() 应用于 Query,以将表限定标签应用于所有列。
  • reduce_columns – 如果为 True,则将调用 Select.reduce_columns() 来删除结果 select() 构造中的同名列,其中一个还通过外键或 WHERE 子句等价关系引用另一个。
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() 来指定多个后缀。


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

相关实践学习
如何在云端创建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 中文文档(二十九)
16 4
|
3天前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(2)
SqlAlchemy 2.0 中文文档(二十九)
20 7
|
3天前
|
SQL 存储 关系型数据库
SqlAlchemy 2.0 中文文档(二十九)(1)
SqlAlchemy 2.0 中文文档(二十九)
16 4
|
3天前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(4)
SqlAlchemy 2.0 中文文档(二十九)
16 4
|
3天前
|
SQL 缓存 前端开发
SqlAlchemy 2.0 中文文档(二十七)(5)
SqlAlchemy 2.0 中文文档(二十七)
10 2
|
3天前
|
SQL 前端开发 关系型数据库
SqlAlchemy 2.0 中文文档(二十七)(2)
SqlAlchemy 2.0 中文文档(二十七)
14 2
|
3天前
|
SQL 测试技术 API
SqlAlchemy 2.0 中文文档(二十)(4)
SqlAlchemy 2.0 中文文档(二十)
10 1
|
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 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(5)
SqlAlchemy 2.0 中文文档(二十九)
11 1