SqlAlchemy 2.0 中文文档(二十一)(4)https://developer.aliyun.com/article/1560622
参数:
*props
–Query.join()
的传入参数,现代用法中的 props 集合应被视为一种或两种参数形式,要么是一个“目标”实体或 ORM 属性绑定的关系,要么是一个目标实体加上一个“on 子句”,该子句可以是 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
返回一个 Query
,它将在加载时使所有实例过期并刷新,或从当前 Session
复用。
自 SQLAlchemy 1.4 起,Query.populate_existing()
方法等同于在 ORM 级别使用 populate_existing
执行选项。有关此选项的更多背景,请参见 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
构造,将在 INSERT、UPDATE 或 DELETE 关键字之后呈现。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()
的调用的“左边缘”,否则,当没有其他方式建立连接点时,通常默认的“连接点”是Query
对象的实体列表中的最左边的实体。
典型的例子:
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.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 的返回值。
表示此 Query 的语句访问器应返回一个 SELECT 语句,该语句对所有列应用标签的形式为 _;这通常用于消除具有相同名称的多个表的列的歧义性。
当 Query 实际发出 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
由此查询表示的完整 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,则首先将在Query
上调用with_labels()
,以将表限定标签应用于所有列。reduce_columns
– 如果为 True,则将在生成的select()
构造上调用Select.reduce_columns()
,以删除通过外键或 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()
来指定多个后缀。
参数:
*suffixes
– 文本或ClauseElement
构造,将在目标子句后呈现。dialect
– 可选的字符串方言名称,它将限制此后缀的呈现仅限于该方言。
method tuples() → Query
返回此 Query
的元组形式。
该方法调用了 Query.only_return_tuples()
方法,并将其值设为 True
,这本身就确保了这个 Query
将始终返回 Row
对象,即使查询只针对单个实体也是如此。它还在类型级别返回一个“类型化”的查询,如果可能的话,将结果行类型化为带有类型的 Tuple
对象。
此方法可以与 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 的 INSERT、UPDATE 和 DELETE 语句 部分。update_args
– 可选字典,如果存在,则作为对象的**kw
传递给底层的update()
构造。 可以用于传递特定于方言的参数,如mysql_limit
,以及其他特殊参数,如update.preserve_parameter_order
。
返回:
数据库的“行计数”功能返回的匹配行数。
另请参阅
启用 ORM 的 INSERT、UPDATE 和 DELETE 语句
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
返回一个带有指定选项的新 Query
,用于 FOR UPDATE
子句。
此方法的行为与 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
或其他可选择对象。
提示文本在使用的数据库后端的适当位置呈现,相对于作为 selectable
参数传递的给定 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
。
虽然通常使用 Session.query()
方法来实例化 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 解释器不需要声明非常大的内存区域,这既费时又导致内存使用过多。 当使用适当的 yield-per 设置时(例如,大约为 1000),即使使用缓冲行的 DBAPI(大多数情况下),从获取数十万行的性能也经常会翻倍。
从 SQLAlchemy 1.4 开始,Query.yield_per()
方法等同于在 ORM 级别使用 yield_per
执行选项。有关此选项的更多背景信息,请参见 使用 Yield Per 获取大型结果集 部分。
另请参见
使用 Yield Per 获取大型结果集
ORM 特定查询构造
本节已移至 附加 ORM API 构造。