SqlAlchemy 2.0 中文文档(二十一)(2)https://developer.aliyun.com/article/1560617
参数:
*suffixes– 将在目标子句后呈现的文本或ClauseElement构造。dialect– 可选的字符串方言名称,将限制仅将此后缀呈现为该方言。
method tuples() → Query
返回这个Query的元组类型形式。
此方法调用Query.only_return_tuples()方法,并将其值设置为True,这本身就确保了这个Query总是返回Row对象,即使查询是针对单个实体的。然后,它还会在类型级别返回一个“类型化”的查询,如果可能的话,该查询将将结果行类型化为具有类型的元组对象。
这种方法可以与Result.tuples()方法进行比较,该方法返回“self”,但从类型的角度来看,返回一个将产生带有类型的Tuple对象的对象。只有当这个Query对象已经是一个类型化的查询对象时,类型才会生效。
版本 2.0 中的新功能。
另请参阅
Result.tuples() - v2 等效方法。
method union(*q: Query) → Self
对一个或多个查询执行 UNION。
例如:
q1 = sess.query(SomeClass).filter(SomeClass.foo=='bar') q2 = sess.query(SomeClass).filter(SomeClass.bar=='foo') q3 = q1.union(q2)
该方法接受多个查询对象,以控制嵌套的级别。一系列union()调用,如下所示:
x.union(y).union(z).all()
将在每个union()上进行嵌套,并生成:
SELECT * FROM (SELECT * FROM (SELECT * FROM X UNION SELECT * FROM y) UNION SELECT * FROM Z)
而:
x.union(y, z).all()
生成:
SELECT * FROM (SELECT * FROM X UNION SELECT * FROM y UNION SELECT * FROM Z)
请注意,许多数据库后端不允许在 UNION、EXCEPT 等内部调用的查询上渲染 ORDER BY。要禁用所有 ORDER BY 子句,包括在映射器上配置的子句,请发出query.order_by(None) - 结果的Query对象将不会在其 SELECT 语句中渲染 ORDER BY。
另请参阅
Select.union() - v2 等效方法。
method union_all(*q: Query) → Self
对一个或多个查询执行 UNION ALL。
与Query.union()的工作方式相同。请参阅该方法以获取用法示例。
另请参阅
Select.union_all() - v2 等效方法。
method update(values: Dict[_DMLColumnArgument, Any], synchronize_session: SynchronizeSessionArgument = 'auto', update_args: Dict[Any, Any] | None = None) → int
使用任意 WHERE 子句执行 UPDATE。
更新数据库中与此查询匹配的行。
例如:
sess.query(User).filter(User.age == 25).\ update({User.age: User.age - 10}, synchronize_session=False) sess.query(User).filter(User.age == 25).\ update({"age": User.age - 10}, synchronize_session='evaluate')
警告
查看 ORM 启用的 INSERT、UPDATE 和 DELETE 语句一节,了解重要的警告和注意事项,包括在使用任意 UPDATE 和 DELETE 与映射器继承配置时的限制。
参数:
values– 一个包含属性名称的字典,或者作为键的映射属性或 SQL 表达式,以及作为值的文字值或 SQL 表达式。如果希望使用 参数排序模式,则值可以作为 2 元组的列表传递;这要求将update.preserve_parameter_order标志也传递给Query.update.update_args字典。synchronize_session– 选择在会话中更新对象属性的策略。参见 ORM-Enabled INSERT, UPDATE, and DELETE statements 章节,讨论这些策略。update_args– 可选字典,如果存在,则会作为对象的update()构造函数的**kw参数传递给底层。可以用于传递特定于方言的参数,如mysql_limit,以及其他特殊参数,如update.preserve_parameter_order。
返回:
数据库的“行计数”功能返回的匹配行数。
另请参见
ORM-Enabled INSERT, UPDATE, and DELETE statements
method value(column: _ColumnExpressionArgument[Any]) → Any
返回与给定列表达式对应的标量结果。
自版本 1.4 起弃用:Query.value() 已弃用,并将在将来的版本中删除。请结合使用 Query.with_entities() 和 Query.scalar()。
method values(*columns: _ColumnsClauseArgument[Any]) → Iterable[Any]
返回一个迭代器,生成与给定列列表对应的结果元组。
自版本 1.4 起弃用:Query.values() 已弃用,并将在将来的版本中删除。请使用 Query.with_entities()。
method where(*criterion: _ColumnExpressionArgument[bool]) → Self
Query.filter() 的别名。
版本 1.4 中的新功能。
另请参见
Select.where() - v2 等效方法。
attribute whereclause
返回此查询的当前 WHERE 条件的只读属性。
返回的值是一个 SQL 表达式构造,如果没有建立条件,则为 None。
另请参见
Select.whereclause - v2 等效属性。
method with_entities(*entities: _ColumnsClauseArgument[Any], **_Query__kw: Any) → Query[Any]
返回一个用给定实体替换 SELECT 列表的新Query。
例如:
# Users, filtered on some arbitrary criterion # and then ordered by related email address q = session.query(User).\ join(User.address).\ filter(User.name.like('%ed%')).\ order_by(Address.email) # given *only* User.id==5, Address.email, and 'q', what # would the *next* User in the result be ? subq = q.with_entities(Address.email).\ order_by(None).\ filter(User.id==5).\ subquery() q = q.join((subq, subq.c.email < Address.email)).\ limit(1)
另请参阅
Select.with_only_columns() - v2 可比较方法。
method with_for_update(*, nowait: bool = False, read: bool = False, of: _ForUpdateOfArgument | None = None, skip_locked: bool = False, key_share: bool = False) → Self
返回一个具有指定FOR UPDATE子句选项的新Query。
此方法的行为与GenerativeSelect.with_for_update()相同。当没有参数调用时,生成的 SELECT 语句将附加一个 FOR UPDATE 子句。当指定了额外的参数时,如 FOR UPDATE NOWAIT 或 LOCK IN SHARE MODE,特定于后端的选项会生效。
例如:
q = sess.query(User).populate_existing().with_for_update(nowait=True, of=User)
在 PostgreSQL 后端上执行上述查询会呈现如下:
SELECT users.id AS users_id FROM users FOR UPDATE OF users NOWAIT
警告
在使用with_for_update来进行急加载关系时,它并不受 SQLAlchemy 官方支持或推荐,并且可能无法与各种数据库后端上的某些查询一起正常工作。当成功使用with_for_update与涉及到joinedload()的查询时,SQLAlchemy 将尝试生成锁定所有涉及的表的 SQL。
注意
通常在使用Query.with_for_update()方法时,结合使用Query.populate_existing()方法是一个好主意。Query.populate_existing()的目的是强制将从 SELECT 中读取的所有数据都填充到返回的 ORM 对象中,即使这些对象已经存在于标识映射中。
另请参阅
GenerativeSelect.with_for_update() - 具有完整参数和行为描述的核心级方法。
Query.populate_existing() - 覆盖已加载到标识映射中的对象的属性。
method with_hint(selectable: _FromClauseArgument, text: str, dialect_name: str = '*') → Self
继承自 HasHints.with_hint() 方法的 HasHints
为给定的可选对象添加索引或其他执行上下文提示到这个Select或其他可选对象中。
提示的文本将根据正在使用的数据库后端在给定的 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_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 - 主要迁移指南)
method with_parent(instance: object, property: attributes.QueryableAttribute[Any] | None = None, from_entity: _ExternalEntityType[Any] | None = None) → Self
添加筛选条件,将给定实例与子对象或集合关联起来,使用其属性状态以及已建立的 relationship() 配置。
自 2.0 版本起弃用:Query.with_parent() 方法在 SQLAlchemy 1.x 系列中被视为遗留,且在 2.0 版本中成为遗留构造。请使用独立构造的 with_parent()。(关于 SQLAlchemy 2.0 的背景信息请参见:SQLAlchemy 2.0 - 主要迁移指南)
此方法使用 with_parent() 函数生成子句,其结果传递给 Query.filter()。
参数与 with_parent() 相同,唯一的例外是给定属性可以为 None,在这种情况下,将针对此 Query 对象的目标映射器执行搜索。
参数:
instance– 具有一些relationship()的实例。property– 表示应使用实例哪个关系来协调父/子关系的类绑定属性。from_entity– 要考虑为左侧的实体。默认为Query本身的“零”实体。
method with_session(session: Session) → Self
返回一个将使用给定Session的Query。
虽然Query对象通常是使用Session.query()方法实例化的,但也可以直接构建Query而无需必然使用Session。这样的Query对象,或者已与不同Session关联的任何Query对象,可以使用此方法生成一个与目标会话关联的新Query对象:
from sqlalchemy.orm import Query query = Query([MyClass]).filter(MyClass.id == 5) result = query.with_session(my_session).one()
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 优化器提示
method with_transformation(fn: Callable[[Query], Query]) → Query
通过给定的函数返回一个经过转换的新Query对象。
例如:
def filter_something(criterion): def transform(q): return q.filter(criterion) return transform q = q.with_transformation(filter_something(x==5))
这允许为Query对象创建临时配方。
method yield_per(count: int) → Self
一次只产出count行。
此方法的目的是在获取非常大的结果集(> 10K 行)时,将结果批处理到子集合中并部分地将其产出,以便 Python 解释器不需要声明非常大的内存区域,这既费时又导致内存使用过多。当使用合适的产出设置(例如大约 1000)时,即使使用缓冲行的 DBAPI(大多数情况下都是),从获取数十万行的性能通常也会提高一倍。
从 SQLAlchemy 1.4 开始,Query.yield_per()方法等同于在 ORM 级别使用yield_per执行选项。有关此选项的更多背景信息,请参阅使用 Yield Per 获取大型结果集部分。
另请参阅
使用 Yield Per 获取大型结果集
ORM 特定查询构造
本节已移至附加 ORM API 构造。
查询对象
Query是根据给定的Session使用Session.query()方法生成的:
q = session.query(SomeMappedClass)
以下是Query对象的完整接口。
| 对象名称 | 描述 |
| Query | ORM 级别的 SQL 构造对象。 |
class sqlalchemy.orm.Query
ORM 级别的 SQL 构造对象。
遗留功能
ORM Query对象是 SQLAlchemy 2.0 的遗留构造。请参阅遗留查询 API 顶部的注释,包括迁移文档的链接。
Query 对象通常最初是使用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.Query (sqlalchemy.sql.expression._SelectFromElements, sqlalchemy.sql.annotation.SupportsCloneAnnotations, sqlalchemy.sql.expression.HasPrefixes, sqlalchemy.sql.expression.HasSuffixes, sqlalchemy.sql.expression.HasHints, sqlalchemy.event.registry.EventTarget, sqlalchemy.log.Identified, sqlalchemy.sql.expression.Generative, sqlalchemy.sql.expression.Executable, typing.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– 一个Session,将与Query关联。可选;也可以通过Query.with_session()方法将Query与Session关联。
另请参阅
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 - 主要迁移指南)
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 执行选项。有关此选项的更多背景,请参阅自动刷新部分。
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
返回一个将给定的 FROM 子句与封闭的 Query 或 select() 相关联的 Query 构造。
此处的方法接受映射类、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 返回单行,这是计数函数的聚合值;然后 Query.count() 方法返回该单个整数值。
警告
重要的是要注意,count() 返回的值 与此 Query 从 .all() 方法等返回的 ORM 对象数不同。当 Query 对象被要求返回完整实体时,将根据主键去重,这意味着如果相同的主键值在结果中出现多次,则只会存在一个该主键的对象。这不适用于针对单个列的查询。
另请参阅
我的查询返回的对象数量与 query.count() 告诉我的不同 - 为什么?
要对特定列进行精细控制以进行计数,跳过子查询的使用或以其他方式控制 FROM 子句,或者使用其他聚合函数,请结合 Session.query() 中的 expression.func 表达式,例如:
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都是 Core 可选择项,这意味着可以通过.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 语句以获取重要的注意事项和警告,包括在使用 mapper 继承配置时使用批量 UPDATE 和 DELETE 时的限制。
SqlAlchemy 2.0 中文文档(二十一)(4)https://developer.aliyun.com/article/1560622