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))
字典形式应该以键的形式包含对应于主键每个元素的映射属性名称。如果映射类具有 id
、version_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
针对CursorResult
和QueryContext
返回一个 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
。
简单关系连接
考虑两个类User
和Address
之间的映射,其中存在一个关系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()方法的顺序很重要。例如,如果我们在连接链中依次指定User
、Item
和Order
,则 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