SqlAlchemy 2.0 中文文档(二十)(4)https://developer.aliyun.com/article/1560352
警告
在调用 with_loader_criteria()
内部的 lambda 中,每个唯一类只调用一次 lambda。自定义函数不应在此 lambda 内部调用。有关“lambda SQL”功能的概述,请参阅使用 Lambda 为语句生成添加显著的速度增益,该功能仅供高级使用。
参数:
entity_or_base
– 一个映射类,或者是一组特定映射类的超类,规则将适用于这些类。where_criteria
–
一个核心 SQL 表达式,应用限制条件。当给定类是具有许多不同映射子类的基类时,这也可以是“lambda:”或 Python 函数,接受目标类作为参数。
注意
为了支持 pickling,使用模块级 Python 函数来生成 SQL 表达式,而不是 lambda 或固定的 SQL 表达式,后者往往不可 picklable。include_aliases
– 如果为 True,则也将规则应用于aliased()
构造。propagate_to_loaders
–
默认为 True,适用于关系加载器,例如延迟加载器。这表示选项对象本身,包括 SQL 表达式,将与每个加载的实例一起传递。设置为False
以防止对象分配给各个实例。
另请参阅
ORM 查询事件 - 包括使用with_loader_criteria()
的示例。
添加全局 WHERE / ON 条件 - 如何将with_loader_criteria()
与SessionEvents.do_orm_execute()
事件结合的基本示例。track_closure_variables
–
当 False 时,lambda 表达式内部的闭包变量不会用作任何缓存键的一部分。这允许在 lambda 表达式内部使用更复杂的表达式,但需要 lambda 确保每次给定特定类时返回相同的 SQL。
新版本 1.4.0b2 中新增。
function sqlalchemy.orm.join(left: _FromClauseArgument, right: _FromClauseArgument, onclause: _OnClauseArgument | None = None, isouter: bool = False, full: bool = False) → _ORMJoin
生成左右子句之间的内部连接。
join()
是对join()
提供的核心连接接口的扩展,其中左右可选择的对象不仅可以是核心可选择的对象,如Table
,还可以是映射类或AliasedClass
实例。"on"子句可以是 SQL 表达式,也可以是引用已配置的relationship()
的 ORM 映射属性。
join()
在现代用法中通常不需要,因为其功能已经封装在Select.join()
和Query.join()
方法中。这些方法比单独使用join()
具有更多的自动化功能。在启用 ORM 的 SELECT 语句中显式使用join()
,需要使用Select.select_from()
方法,如下所示:
from sqlalchemy.orm import join stmt = select(User).\ select_from(join(User, Address, User.addresses)).\ filter(Address.email_address=='foo@bar.com')
在现代的 SQLAlchemy 中,上述连接可以更简洁地编写为:
stmt = select(User).\ join(User.addresses).\ filter(Address.email_address=='foo@bar.com')
警告
直接使用join()
可能无法与现代 ORM 选项(如with_loader_criteria()
)正常工作。强烈建议在创建 ORM 连接时使用诸如Select.join()
和Select.join_from()
等方法提供的惯用连接模式。
另请参阅
连接 - 了解 ORM 连接模式的背景知识
function sqlalchemy.orm.outerjoin(left: _FromClauseArgument, right: _FromClauseArgument, onclause: _OnClauseArgument | None = None, full: bool = False) → _ORMJoin
生成左外连接(left outer join)左边和右边子句之间的关联。
这是join()
函数的“外连接”版本,具有相同的行为,只是生成了 OUTER JOIN。请参阅该函数的文档以获取其他用法细节。
function sqlalchemy.orm.with_parent(instance: object, prop: attributes.QueryableAttribute[Any], from_entity: _EntityType[Any] | None = None) → ColumnElement[bool]
创建过滤条件,将此查询的主实体与给定的相关实例相关联,使用已建立的relationship()
配置。
例如:
stmt = select(Address).where(with_parent(some_user, User.addresses))
渲染的 SQL 与在给定父对象上的惰性加载程序触发时所渲染的 SQL 相同,这意味着在 Python 中从父对象中取得适当的状态而无需将父表的联接渲染到渲染的语句中。
给定的属性也可以使用 PropComparator.of_type()
来指示条件的左侧:
a1 = aliased(Address) a2 = aliased(Address) stmt = select(a1, a2).where( with_parent(u1, User.addresses.of_type(a2)) )
上述用法等同于使用 from_entity()
参数:
a1 = aliased(Address) a2 = aliased(Address) stmt = select(a1, a2).where( with_parent(u1, User.addresses, from_entity=a2) )
参数:
instance
– 一个具有一些relationship()
的实例。property
– 类绑定属性,表示应该使用实例中的哪种关系来协调父/子关系。from_entity
–
要考虑为左侧的实体。默认为Query
本身的“零”实体。
新版 1.2 中新增。#### 从 ORM 启用的 SELECT 和 DML 语句中检查实体和列
select()
构造,以及 insert()
、update()
和 delete()
构造(对于后两个 DML 构造,在 SQLAlchemy 1.4.33 中),都支持检查这些语句所针对的实体,以及将在结果集中返回的列和数据类型。
对于 Select
对象,此信息可从 Select.column_descriptions
属性获得。此属性的操作方式与传统的 Query.column_descriptions
属性相同。返回的格式是一个字典列表:
>>> from pprint import pprint >>> user_alias = aliased(User, name="user2") >>> stmt = select(User, User.id, user_alias) >>> pprint(stmt.column_descriptions) [{'aliased': False, 'entity': <class 'User'>, 'expr': <class 'User'>, 'name': 'User', 'type': <class 'User'>}, {'aliased': False, 'entity': <class 'User'>, 'expr': <....InstrumentedAttribute object at ...>, 'name': 'id', 'type': Integer()}, {'aliased': True, 'entity': <AliasedClass ...; User>, 'expr': <AliasedClass ...; User>, 'name': 'user2', 'type': <class 'User'>}]
当 Select.column_descriptions
与非 ORM 对象一起使用,如普通的 Table
或 Column
对象时,条目将在所有情况下包含有关返回的各个列的基本信息:
>>> stmt = select(user_table, address_table.c.id) >>> pprint(stmt.column_descriptions) [{'expr': Column('id', Integer(), table=<user_account>, primary_key=True, nullable=False), 'name': 'id', 'type': Integer()}, {'expr': Column('name', String(), table=<user_account>, nullable=False), 'name': 'name', 'type': String()}, {'expr': Column('fullname', String(), table=<user_account>), 'name': 'fullname', 'type': String()}, {'expr': Column('id', Integer(), table=<address>, primary_key=True, nullable=False), 'name': 'id_1', 'type': Integer()}]
版本 1.4.33 中的更改:当用于未启用 ORM 的 Select
时,Select.column_descriptions
属性现在返回一个值。先前,这会引发 NotImplementedError
。
对于insert()
,update()
和 delete()
构造,存在两个单独的属性。一个是UpdateBase.entity_description
,它返回有关 DML 构造将影响的主要 ORM 实体和数据库表的信息:
>>> from sqlalchemy import update >>> stmt = update(User).values(name="somename").returning(User.id) >>> pprint(stmt.entity_description) {'entity': <class 'User'>, 'expr': <class 'User'>, 'name': 'User', 'table': Table('user_account', ...), 'type': <class 'User'>}
Tip
UpdateBase.entity_description
包括一个条目 "table"
,实际上是语句要插入、更新或删除的表,这通常不与类可能被映射到的 SQL “selectable” 相同。例如,在联合表继承场景中,"table"
将引用给定实体的本地表。
另一个是 UpdateBase.returning_column_descriptions
,它以一种与Select.column_descriptions
大致相似的方式提供了有关 RETURNING 集合中存在的列的信息:
>>> pprint(stmt.returning_column_descriptions) [{'aliased': False, 'entity': <class 'User'>, 'expr': <sqlalchemy.orm.attributes.InstrumentedAttribute ...>, 'name': 'id', 'type': Integer()}]
版本 1.4.33 中的新内容:增加了 UpdateBase.entity_description
和 UpdateBase.returning_column_descriptions
属性。
其他 ORM API 构造
对象名称 | 描述 |
aliased(element[, alias, name, flat, …]) | 生成给定元素的别名,通常是 AliasedClass 实例。 |
AliasedClass | 代表映射类的“别名”形式,可用于查询。 |
AliasedInsp | 为AliasedClass 对象提供检查接口。 |
Bundle | 由一个命名空间下的一个Query 返回的 SQL 表达式组合。 |
join(left, right[, onclause, isouter, …]) | 在左右子句之间产生内连接。 |
outerjoin(left, right[, onclause, full]) | 在左右子句之间生成左外连接。 |
with_loader_criteria(entity_or_base, where_criteria[, loader_only, include_aliases, …]) | 为特定实体的所有出现添加额外的 WHERE 条件以加载。 |
with_parent(instance, prop[, from_entity]) | 创建过滤条件,将此查询的主要实体与给定的相关实例关联起来,使用已建立的relationship() 配置。 |
function sqlalchemy.orm.aliased(element: _EntityType[_O] | FromClause, alias: FromClause | None = None, name: str | None = None, flat: bool = False, adapt_on_names: bool = False) → AliasedClass[_O] | FromClause | AliasedType[_O]
生成给定元素的别名,通常是一个AliasedClass
实例。
例如:
my_alias = aliased(MyClass) stmt = select(MyClass, my_alias).filter(MyClass.id > my_alias.id) result = session.execute(stmt)
aliased()
函数用于创建将映射类映射到新可选择项的临时映射。 默认情况下,可选择项是使用FromClause.alias()
方法从通常映射的可选择项(通常是Table
)生成的。但是,aliased()
也可以用于将类链接到新的select()
语句。 此外,with_polymorphic()
函数是aliased()
的变体,旨在指定所谓的“多态可选择项”,该可选择项对应于一次性联接继承子类的联合。
为方便起见,aliased()
函数还接受普通的FromClause
构造,例如Table
或select()
构造。在这些情况下,该对象上调用FromClause.alias()
方法,并返回新的Alias
对象。在这种情况下,返回的Alias
不是 ORM 映射的。
另请参阅
ORM 实体别名 - 在 SQLAlchemy 统一教程中
选择 ORM 别名 - 在 ORM 查询指南中
参数:
element
- 要别名化的元素。通常是一个映射的类,但出于方便起见,也可以是一个FromClause
元素。alias
- 可选的可选择单元,将元素映射到该单元。这通常用于将对象链接到子查询,并且应该是一个别名选择构造,就像从Query.subquery()
方法或Select.subquery()
或Select.alias()
方法从select()
构造中产生的那样。name
- 可选的字符串名称,用于别名,如果未由alias
参数指定。该名称,除其他外,形成了由Query
对象返回的元组访问的属性名称。在创建Join
对象的别名时不受支持。flat
– 布尔值,将传递给FromClause.alias()
调用,以便将Join
对象的别名别名为加入其中的各个表,而不是创建子查询。这通常由所有现代数据库支持,关于右嵌套连接通常会产生更有效的查询。adapt_on_names
–
如果为 True,则在将 ORM 实体的映射列与给定可选择的列进行映射时将使用更宽松的“匹配” - 如果给定的可选择没有与实体上的列对应的列,则将执行基于名称的匹配。这种用例是当将实体与一些派生可选择关联时,例如使用聚合函数的可选择:
class UnitPrice(Base): __tablename__ = 'unit_price' ... unit_id = Column(Integer) price = Column(Numeric) aggregated_unit_price = Session.query( func.sum(UnitPrice.price).label('price') ).group_by(UnitPrice.unit_id).subquery() aggregated_unit_price = aliased(UnitPrice, alias=aggregated_unit_price, adapt_on_names=True)
- 上面,对
aggregated_unit_price
上的函数引用.price
将返回func.sum(UnitPrice.price).label('price')
列,因为它与名称“price”匹配。通常情况下,“price”函数不会与实际的UnitPrice.price
列有任何“列对应”,因为它不是原始列的代理。
class sqlalchemy.orm.util.AliasedClass
表示用于与查询一起使用的映射类的“别名”形式。
ORM 中的alias()
构造的等价物,此对象使用__getattr__
方案模仿映射类,并维护对真实Alias
对象的引用。
AliasedClass
的一个主要目的是在 ORM 生成的 SQL 语句中作为一个替代品,使得现有的映射实体可以在多个上下文中使用。一个简单的例子:
# find all pairs of users with the same name user_alias = aliased(User) session.query(User, user_alias).\ join((user_alias, User.id > user_alias.id)).\ filter(User.name == user_alias.name)
AliasedClass
还能够将现有的映射类映射到一个全新的可选择项,只要此可选择项与现有的映射可选择项兼容,并且它还可以被配置为relationship()
的目标。请参阅下面的链接获取示例。
AliasedClass
对象通常使用aliased()
函数构造。当使用with_polymorphic()
函数时,还会使用附加配置生成该对象。
结果对象是 AliasedClass
的一个实例。此对象实现了与原始映射类相同的属性和方法接口,允许 AliasedClass
兼容任何在原始类上工作的属性技术,包括混合属性(参见混合属性)。
可以使用 inspect()
检查 AliasedClass
的底层 Mapper
、别名可选项和其他信息:
from sqlalchemy import inspect my_alias = aliased(MyClass) insp = inspect(my_alias)
结果检查对象是 AliasedInsp
的一个实例。
另请参阅
aliased()
with_polymorphic()
与别名类的关系
带窗口函数的行限制关系
类签名
类 sqlalchemy.orm.AliasedClass
(sqlalchemy.inspection.Inspectable
,sqlalchemy.orm.ORMColumnsClauseRole
)
class sqlalchemy.orm.util.AliasedInsp
为 AliasedClass
对象提供检查接口。
使用 inspect()
函数给定 AliasedClass
返回 AliasedInsp
对象:
from sqlalchemy import inspect from sqlalchemy.orm import aliased my_alias = aliased(MyMappedClass) insp = inspect(my_alias)
AliasedInsp
上的属性包括:
entity
- 代表的AliasedClass
。mapper
-Mapper
映射了底层类。selectable
- 最终表示别名的Alias
构造或Select
构造。name
- 别名的名称。当从Query
中的结果元组中返回时,也用作属性名称。with_polymorphic_mappers
- 包含表示选择结构中所有那些表示的Mapper
对象的集合,用于AliasedClass
。polymorphic_on
- 作为多态加载的“鉴别器”使用的替代列或 SQL 表达式。
另请参见
运行时检测 API
类签名
类 sqlalchemy.orm.AliasedInsp
(sqlalchemy.orm.ORMEntityColumnsClauseRole
, sqlalchemy.orm.ORMFromClauseRole
, sqlalchemy.sql.cache_key.HasCacheKey
, sqlalchemy.orm.base.InspectionAttr
, sqlalchemy.util.langhelpers.MemoizedSlots
, sqlalchemy.inspection.Inspectable
, typing.Generic
)
class sqlalchemy.orm.Bundle
一组由 Query
返回的 SQL 表达式,在一个命名空间下。
Bundle
实质上允许嵌套列导向 Query
对象返回的基于元组的结果。它还可以通过简单的子类扩展,其中主要的重写功能是如何返回表达式集,允许后处理以及自定义返回类型,而不涉及 ORM 身份映射类。
另请参见
使用 Bundles 分组选择的属性
成员
init(), c, columns, create_row_processor(), is_aliased_class, is_bundle, is_clause_element, is_mapper, label(), single_entity
类签名
类 sqlalchemy.orm.Bundle
(sqlalchemy.orm.ORMColumnsClauseRole
, sqlalchemy.sql.annotation.SupportsCloneAnnotations
, sqlalchemy.sql.cache_key.MemoizedHasCacheKey
, sqlalchemy.inspection.Inspectable
, sqlalchemy.orm.base.InspectionAttr
)
method __init__(name: str, *exprs: _ColumnExpressionArgument[Any], **kw: Any)
构造一个新的 Bundle
。
例如:
bn = Bundle("mybundle", MyClass.x, MyClass.y) for row in session.query(bn).filter( bn.c.x == 5).filter(bn.c.y == 4): print(row.mybundle.x, row.mybundle.y)
参数:
name
– bundle 的名称。*exprs
– 组成 bundle 的列或 SQL 表达式。single_entity=False
– 如果为 True,则此Bundle
的行可以像映射实体一样在任何封闭元组之外返回。
attribute c: ReadOnlyColumnCollection[str, KeyedColumnElement[Any]]
Bundle.columns
的别名。
attribute columns: ReadOnlyColumnCollection[str, KeyedColumnElement[Any]]
此 Bundle
引用的 SQL 表达式的命名空间。
例如:
bn = Bundle("mybundle", MyClass.x, MyClass.y) q = sess.query(bn).filter(bn.c.x == 5)
支持嵌套捆绑:
b1 = Bundle("b1", Bundle('b2', MyClass.a, MyClass.b), Bundle('b3', MyClass.x, MyClass.y) ) q = sess.query(b1).filter( b1.c.b2.c.a == 5).filter(b1.c.b3.c.y == 9)
请参见
Bundle.c
method create_row_processor(query: Select[Any], procs: Sequence[Callable[[Row[Any]], Any]], labels: Sequence[str]) → Callable[[Row[Any]], Any]
生成此 Bundle
的“行处理”函数。
可以被子类覆盖以在获取结果时提供自定义行为。 方法在查询执行时传递语句对象和一组“行处理”函数;给定结果行时,这些处理函数将返回单个属性值,然后可以将其调整为任何类型的返回数据结构。
下面的示例说明了用直接的 Python 字典替换通常的 Row
返回结构:
from sqlalchemy.orm import Bundle class DictBundle(Bundle): def create_row_processor(self, query, procs, labels): 'Override create_row_processor to return values as dictionaries' def proc(row): return dict( zip(labels, (proc(row) for proc in procs)) ) return proc
上述 Bundle
的结果将返回字典值:
bn = DictBundle('mybundle', MyClass.data1, MyClass.data2) for row in session.execute(select(bn)).where(bn.c.data1 == 'd1'): print(row.mybundle['data1'], row.mybundle['data2'])
attribute is_aliased_class = False
如果此对象是 AliasedClass
的实例,则为 True。
attribute is_bundle = True
如果此对象是 Bundle
的实例,则为 True。
attribute is_clause_element = False
如果此对象是 ClauseElement
的实例,则为 True。
attribute is_mapper = False
如果此对象是 Mapper
的实例,则为 True。
method label(name)
提供此 Bundle
的副本并传递一个新的标签。
attribute single_entity = False
如果为 True,则查询单个 Bundle 将返回单个实体,而不是键入元组中的元素。
function sqlalchemy.orm.with_loader_criteria(entity_or_base: _EntityType[Any], where_criteria: _ColumnExpressionArgument[bool] | Callable[[Any], _ColumnExpressionArgument[bool]], loader_only: bool = False, include_aliases: bool = False, propagate_to_loaders: bool = True, track_closure_variables: bool = True) → LoaderCriteriaOption
为特定实体的所有出现添加额外的 WHERE 条件到加载中。
版本 1.4 中的新功能。
with_loader_criteria()
选项旨在向查询中的特定类型的实体添加限制条件,全局,这意味着它将应用于实体在 SELECT 查询中出现的方式以及在任何子查询、连接条件和关系加载中,包括急切加载和惰性加载,而无需在查询的任何特定部分指定它。 渲染逻辑使用与单表继承相同的系统来确保某个特定的鉴别器应用于表。
例如,使用 2.0 样式 查询,我们可以限制 User.addresses
集合的加载方式,而不管使用的加载类型:
from sqlalchemy.orm import with_loader_criteria stmt = select(User).options( selectinload(User.addresses), with_loader_criteria(Address, Address.email_address != 'foo')) )
上述中,“selectinload” 用于 User.addresses
将应用给定的过滤条件到 WHERE 子句。
另一个示例,其中过滤将应用于连接的 ON 子句,在此示例中使用 1.x 样式 查询:
q = session.query(User).outerjoin(User.addresses).options( with_loader_criteria(Address, Address.email_address != 'foo')) )
with_loader_criteria()
的主要目的是在SessionEvents.do_orm_execute()
事件处理程序中使用它,以确保特定实体的所有出现都以某种方式被过滤,例如,为访问控制角色过滤。它还可以用于应用条件于关系加载。在下面的示例中,我们可以将一组特定规则应用于特定Session
发出的所有查询:
session = Session(bind=engine) @event.listens_for("do_orm_execute", session) def _add_filtering_criteria(execute_state): if ( execute_state.is_select and not execute_state.is_column_load and not execute_state.is_relationship_load ): execute_state.statement = execute_state.statement.options( with_loader_criteria( SecurityRole, lambda cls: cls.role.in_(['some_role']), include_aliases=True ) )
在上面的示例中,SessionEvents.do_orm_execute()
事件将拦截使用Session
发出的所有查询。对于那些是 SELECT 语句且不是属性或关系加载的查询,将为查询添加一个自定义的with_loader_criteria()
选项。with_loader_criteria()
选项将在给定语句中使用,并且还将自动传播到所有从此查询继承的关系加载中。
给定的 criteria 参数是一个接受 cls 参数的lambda
。给定的类将扩展以包括所有映射的子类,本身不需要是映射的类。
提示
当在与contains_eager()
加载器选项一起使用with_loader_criteria()
选项时,重要的是要注意,with_loader_criteria()
仅影响决定以何种方式呈现 SQL 的查询的部分,这涉及 WHERE 和 FROM 子句。 contains_eager()
选项不影响 SELECT 语句在列之外的呈现,因此与with_loader_criteria()
选项没有任何交互。但是,事情的“工作”方式是contains_eager()
应该与某种已经选择额外实体的查询一起使用,而with_loader_criteria()
可以应用其额外的条件。
在下面的示例中,假设映射关系为 A -> A.bs -> B
,给定的 with_loader_criteria()
选项将影响 JOIN 的呈现方式:
stmt = select(A).join(A.bs).options( contains_eager(A.bs), with_loader_criteria(B, B.flag == 1) )
在上面的示例中,给定的 with_loader_criteria()
选项将影响由 .join(A.bs)
指定的 JOIN 的 ON 子句,因此按预期应用。contains_eager()
选项的效果是将 B
的列添加到列子句中:
SELECT b.id, b.a_id, b.data, b.flag, a.id AS id_1, a.data AS data_1 FROM a JOIN b ON a.id = b.a_id AND b.flag = :flag_1
在上述语句中使用 contains_eager()
选项对 with_loader_criteria()
选项的行为没有影响。如果省略了 contains_eager()
选项,则 SQL 将与 FROM 和 WHERE 子句相同,其中 with_loader_criteria()
继续将其条件添加到 JOIN 的 ON 子句中。添加 contains_eager()
只影响列子句,即添加了针对 B
的其他列,然后 ORM 消耗这些列以生成 B
实例。
警告
在对 with_loader_criteria()
的调用内部使用 lambda 只会 对每个唯一类调用一次。自定义函数不应在此 lambda 内调用。有关“lambda SQL”功能的概述,请参阅使用 Lambdas 为语句生成带来显著速度提升,这仅供高级使用。
参数:
entity_or_base
– 映射类,或者是一组特定映射类的超类,将应用规则到其中。where_criteria
–
核心 SQL 表达式,应用限制条件。当给定类是一个具有许多不同映射子类的基类时,这也可以是一个“lambda:”或 Python 函数,接受目标类作为参数。
注意
为了支持 pickle,使用模块级 Python 函数生成 SQL 表达式,而不是 lambda 或固定的 SQL 表达式,后者往往不可 picklable。include_aliases
– 如果为 True,则也将规则应用于aliased()
构造。propagate_to_loaders
–
默认为 True,适用于关系加载器,如惰性加载器。这表示选项对象本身,包括 SQL 表达式,将随每个加载的实例一起传递。将其设置为False
可防止将对象分配给各个实例。
另请参阅
ORM 查询事件 - 包括使用with_loader_criteria()
的示例。
添加全局 WHERE / ON 条件 - 如何将with_loader_criteria()
与SessionEvents.do_orm_execute()
事件结合的基本示例。track_closure_variables
-
当为 False 时,lambda 表达式中的闭包变量将不会作为任何缓存键的一部分。这允许在 lambda 表达式中使用更复杂的表达式,但要求 lambda 确保每次给定特定类时返回相同的 SQL。
新版本 1.4.0b2 中新增。
function sqlalchemy.orm.join(left: _FromClauseArgument, right: _FromClauseArgument, onclause: _OnClauseArgument | None = None, isouter: bool = False, full: bool = False) → _ORMJoin
在左右子句之间产生内连接。
join()
是对 join()
提供的核心连接接口的扩展,其中左右可选择的对象不仅可以是核心可选择对象,如 Table
,还可以是映射类或 AliasedClass
实例。“on” 子句可以是 SQL 表达式,也可以是引用已配置的 relationship()
的 ORM 映射属性。
在现代用法中,通常不常用 join()
,因为其功能已封装在 Select.join()
和 Query.join()
方法中。这两种方法在自动化方面远远超出了 join()
本身。在启用 ORM 的 SELECT 语句中显式使用 join()
涉及使用 Select.select_from()
方法,如下所示:
from sqlalchemy.orm import join stmt = select(User).\ select_from(join(User, Address, User.addresses)).\ filter(Address.email_address=='foo@bar.com')
在现代 SQLAlchemy 中,上述连接可以更简洁地写为:
stmt = select(User).\ join(User.addresses).\ filter(Address.email_address=='foo@bar.com')
警告
直接使用join()
可能无法与现代 ORM 选项(如with_loader_criteria()
)正常工作。强烈建议在创建 ORM 连接时使用由Select.join()
和Select.join_from()
等方法提供的成语连接模式。
另请参阅
连接 - 在 ORM 查询指南中了解成语连接模式的背景
function sqlalchemy.orm.outerjoin(left: _FromClauseArgument, right: _FromClauseArgument, onclause: _OnClauseArgument | None = None, full: bool = False) → _ORMJoin
在左侧和右侧子句之间产生左外连接。
这是join()
函数的“外连接”版本,具有相同的行为,只是生成了一个外连接。有关其他用法细节,请参阅该函数的文档。
function sqlalchemy.orm.with_parent(instance: object, prop: attributes.QueryableAttribute[Any], from_entity: _EntityType[Any] | None = None) → ColumnElement[bool]
创建过滤条件,将此查询的主实体与给定的相关实例关联起来,使用已建立的relationship()
配置。
例如:
stmt = select(Address).where(with_parent(some_user, User.addresses))
渲染的 SQL 与在给定父对象上的惰性加载器触发时渲染的 SQL 相同,这意味着在 Python 中从父对象中获取适当的状态而无需在渲染语句中渲染到父表的连接。
给定属性还可以利用PropComparator.of_type()
指示条件的左侧:
a1 = aliased(Address) a2 = aliased(Address) stmt = select(a1, a2).where( with_parent(u1, User.addresses.of_type(a2)) )
上述用法等同于使用from_entity()
参数:
a1 = aliased(Address) a2 = aliased(Address) stmt = select(a1, a2).where( with_parent(u1, User.addresses, from_entity=a2) )
参数:
instance
– 具有某些relationship()
的实例。property
– 类绑定属性,指示应使用实例中的哪个关系来协调父/子关系。from_entity
–
要考虑为左侧的实体。默认为Query
本身的“零”实体。
版本 1.2 中的新功能。