Release: 1.4.25 | Release Date: September 22, 2021

SQLAlchemy 1.4 Documentation

查询API

本节介绍ORM的API参考 Query 对象。有关如何使用此对象的演练,请参见 对象关系教程(1.x API) .

查询对象

Query 是根据给定的 Session ,使用 Session.query() 方法:

q = session.query(SomeMappedClass)

下面是 Query 对象。

Object Name Description

Query

ORM级SQL构造对象。

class sqlalchemy.orm.Query(entities, session=None)

ORM级SQL构造对象。

Query 是ORM生成的所有SELECT语句的源,这两个语句都是由最终用户查询操作以及相关集合加载等高级内部操作所制定的。它具有一个生成接口,在该接口中,连续调用返回一个新的 Query 对象,前者的副本,以及与之关联的其他条件和选项。

Query 对象通常最初是使用 Session.query() 方法 Session 在不太常见的情况下,通过实例化 Query 直接并与 Session 使用 Query.with_session() 方法。

要完整地走完…… Query 用法,请参阅 对象关系教程(1.x API)

类签名

class sqlalchemy.orm.Query (sqlalchemy.sql.expression._SelectFromElements, sqlalchemy.sql.annotation.SupportsCloneAnnotations, sqlalchemy.sql.expression.HasPrefixes, sqlalchemy.sql.expression.HasSuffixes, sqlalchemy.sql.expression.HasHints, sqlalchemy.sql.expression.Executable)

method sqlalchemy.orm.Query.prefix_with(*expr, **kw)

inherited from the HasPrefixes.prefix_with() method of 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() .

参数
  • *expr -- 文本或 ClauseElement 在插入、更新或删除关键字后呈现的构造。

  • **kw -- 只接受一个关键字“dialect”。这是一个可选的字符串方言名称,它将此前缀的呈现限制为仅显示该方言。

method sqlalchemy.orm.Query.suffix_with(*expr, **kw)

inherited from the HasSuffixes.suffix_with() method of HasSuffixes

在语句后面整体添加一个或多个表达式。

这用于在某些构造上支持后端特定的后缀关键字。

例如。::

stmt = select(col1, col2).cte().suffix_with(
    "cycle empno set y_cycle to 1 default 0", dialect="oracle")

可以通过多次调用指定多个后缀 HasSuffixes.suffix_with() .

参数
  • *expr -- 文本或 ClauseElement 在目标子句之后呈现的构造。

  • **kw -- 只接受一个关键字“dialect”。这是一个可选的字符串方言名称,它将此后缀的呈现限制为仅限于该方言。

method sqlalchemy.orm.Query.with_hint(selectable, text, dialect_name='*')

inherited from the HasHints.with_hint() method of HasHints

为给定的可选对象添加索引或其他执行上下文提示 Select 或其他可选对象。

提示的文本呈现在正在使用的数据库后端的适当位置,相对于给定的 TableAlias 作为传递 selectable 争论。方言实现通常使用带有标记的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", 'sybase')
method sqlalchemy.orm.Query.with_statement_hint(text, dialect_name='*')

inherited from the HasHints.with_statement_hint() method of HasHints

为此添加语句提示 Select 或其他可选对象。

这种方法类似于 Select.with_hint() 但它不需要单独的表,而是作为一个整体应用于语句。

这里的提示特定于后端数据库,可能包括诸如隔离级别、文件指令、fetch指令等指令。

1.0.0 新版功能.

参见

Select.with_hint()

Select.prefix_with() -通用的SELECT前缀,也可以适合一些数据库特定的提示语法,如MySQL优化器提示

method sqlalchemy.orm.Query.__init__(entities, session=None)

构建一个 Query 直接。

例如。::

q = Query([User, Address], session=some_session)

以上相当于:

q = some_session.query(User, Address)
参数
method sqlalchemy.orm.Query.add_column(column)

将列表达式添加到要返回的结果列列表中。

1.4 版后已移除: Query.add_column() is deprecated and will be removed in a future release. Please use Query.add_columns()

method sqlalchemy.orm.Query.add_columns(*column)

将一个或多个列表达式添加到要返回的结果列列表中。

method sqlalchemy.orm.Query.add_entity(entity, alias=None)

将映射的实体添加到要返回的结果列列表中。

method sqlalchemy.orm.Query.all()

返回由此表示的结果 Query 作为一个列表。

这将导致执行底层SQL语句。

警告

这个 Query 对象在被要求返回由完整的ORM映射实体组成的序列或迭代器时,将 基于主键对条目进行重复数据消除 . 有关详细信息,请参阅常见问题解答。

method sqlalchemy.orm.Query.apply_labels()

1.4 版后已移除: 这个 Query.with_labels()Query.apply_labels() 方法被认为是SQLAlChemy 1.x系列的遗留方法,将在2.0中删除。请改用set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)。(有关SQLAlChemy 2.0的背景信息位于: 迁移到Alchemy )

method sqlalchemy.orm.Query.as_scalar()

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

1.4 版后已移除: 这个 Query.as_scalar() 方法已弃用,将在将来的版本中删除。请参考 Query.scalar_subquery() .

method sqlalchemy.orm.Query.autoflush(setting)

返回具有特定“autoflush”设置的查询。

从SQLAlChemy 1.4开始, Query.autoflush() 方法等效于使用 autoflush ORM级别的执行选项。请参阅部分 自动冲洗 有关此选项的更多背景信息,请参阅。

attribute sqlalchemy.orm.Query.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
    }
]
method sqlalchemy.orm.Query.correlate(*fromclauses)

返回A Query 将给定的FROM子句与封闭子句相关联的构造 Queryselect() .

这里的方法接受映射类, aliased() 构造,以及 mapper() 构造作为参数,除了适当的表达式构造之外,还解析为表达式构造。

相关参数最终传递给 Select.correlate() 强制表达式构造之后。

相关参数在以下情况下生效: Query.from_self() 使用,或当 Query.subquery() 嵌入到另一个 select() 构造。

method sqlalchemy.orm.Query.count()

返回一个行数这个由这个组成的SQL Query 会回来。

这将为此查询生成SQL,如下所示:

SELECT count(1) AS count_1 FROM (
    SELECT <rest of query follows...>
) AS anon_1

上面的SQL返回一行,这是count函数的聚合值 Query.count() 方法然后返回该单个整数值。

警告

注意count()返回的值是 与此查询从.all()方法等方法返回的ORM对象数不同 . 这个 Query 对象在被要求返回完整实体时,将 基于主键对条目进行重复数据消除 ,这意味着如果相同的主键值将多次出现在结果中,则只会出现该主键的一个对象。这不适用于针对单个列的查询。

对于要计数的特定列的细粒度控制,若要跳过子查询的使用或对FROM子句的其他控制,或使用其他聚合函数,请使用 expression.func 表达式与 Session.query() ,即:

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)))
method sqlalchemy.orm.Query.cte(name=None, recursive=False, nesting=False)

返回由该语句表示的完整select语句 Query 表示为公用表表达式(CTE)。

参数和用法与 SelectBase.cte() 方法;有关详细信息,请参阅该方法。

这是 PostgreSQL WITH RECURSIVE example 。请注意,在此示例中, included_parts cte and the incl_alias alias of it are Core selectables, which means the columns are accessed via the .c. 属性。这个 parts_alias 对象是一个 aliased() 对象的实例 Part 实体,因此列映射属性可直接使用::

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)

参见

HasCTE.cte()

method sqlalchemy.orm.Query.delete(synchronize_session='evaluate')

使用任意WHERE子句执行DELETE。

从数据库中删除与此查询匹配的行。

例如。::

sess.query(User).filter(User.age == 25).\
    delete(synchronize_session=False)

sess.query(User).filter(User.age == 25).\
    delete(synchronize_session='evaluate')

警告

见剖面图 使用任意WHERE子句更新和删除 对于重要的警告和警告,包括对映射器继承配置使用批量更新和删除时的限制。

参数

synchronize_session -- 选择更新会话中对象的属性的策略。参见章节 使用任意WHERE子句更新和删除 讨论这些策略。

返回

由数据库的“行数”功能返回的匹配行数。

method sqlalchemy.orm.Query.distinct(*expr)

应用一 DISTINCT 到查询并返回新生成的 Query .

注解

ORM级别 distinct() 调用包含的逻辑将自动从查询的order by添加列到select语句的columns子句,以满足数据库后端在使用distinct时将order by列作为select列表的一部分的常见需求。这些栏目 不是 添加到实际由 Query 但是,这不会影响结果。当使用 Query.statement 但是,访问器。

2.0 版后已移除: 此逻辑已弃用,将在SQLAlchemy 2.0中删除。看到了吗 对其他列使用DISTINCT,但只选择实体 在2.0中描述这个用例。

参数

*expr -- 可选列表达式。当存在时,PostgreSQL方言将呈现 DISTINCT ON (<expressions>) 构造。。已弃用::1.4使用 * 其他方言中的expr已被弃用,并将提高 CompileError 在未来的版本中。

method sqlalchemy.orm.Query.enable_assertions(value)

控制是否生成断言。

当设置为false时,返回的查询不会在某些操作之前断言其状态,包括调用filter()时未应用限制/偏移量,调用get()时不存在条件,调用filter()/order_by()/group_by()等时不存在“from_statement()”。自定义查询子类使用这种更为宽松的模式来指定标准或常规使用模式之外的其他修饰符。

应该注意确保使用模式是可能的。例如,由from_statement()应用的语句将重写filter()或order_by()设置的任何条件。

method sqlalchemy.orm.Query.enable_eagerloads(value)

控制是否呈现预先连接和子查询。

当设置为false时,返回的查询将不会呈现任何 joinedload()subqueryload() 选项或映射器级别 lazy='joined'/lazy='subquery' 配置。

这主要用于将查询语句嵌套到子查询或其他可选查询中时,或者在使用 Query.yield_per() .

method sqlalchemy.orm.Query.except_(*q)

针对一个或多个查询生成此查询的except。

工作方式与 Query.union() . 有关用法示例,请参见该方法。

method sqlalchemy.orm.Query.except_all(*q)

针对一个或多个查询生成一个except all查询。

工作方式与 Query.union() . 有关用法示例,请参见该方法。

method sqlalchemy.orm.Query.execution_options(**kwargs)

设置在执行期间生效的非SQL选项。

此处允许的选项包括 Connection.execution_options() ,以及一系列特定于ORM的选项:

populate_existing=True - equivalent to using Query.populate_existing()

autoflush=True|False - equivalent to using Query.autoflush()

yield_per=<value> - equivalent to using Query.yield_per()

请注意 stream_results 如果 Query.yield_per() 方法或执行选项。

当使用 2.0 style 通过 Session.execution_options 参数。

1.4 新版功能: -将ORM选项添加到 Query.execution_options()

method sqlalchemy.orm.Query.exists()

将查询转换为窗体的exists子查询的便利方法exists(从…在哪里……)

例如。::

q = session.query(User).filter(User.name == 'fred')
session.query(q.exists())

生成类似以下内容的SQL:

SELECT EXISTS (
    SELECT 1 FROM users WHERE users.name = :name_1
) AS anon_1

exists结构通常用于where子句:

session.query(User.id).filter(q.exists()).scalar()

请注意,某些数据库(如SQL Server)不允许在select的columns子句中存在exists表达式。要基于“存在”选择一个简单的布尔值,请使用 literal() ::

from sqlalchemy import literal

session.query(literal(True)).filter(q.exists()).scalar()
method sqlalchemy.orm.Query.filter(*criterion)

将给定的筛选条件应用于 Query ,使用SQL表达式。

例如。::

session.query(MyClass).filter(MyClass.name == 'some name')

多个条件可以指定为逗号分隔;其效果是它们将使用 and_() 功能:

session.query(MyClass).\
    filter(MyClass.name == 'some name', MyClass.id > 5)

条件是任何适用于select的where子句的SQL表达式对象。字符串表达式通过 text() 构造。

参见

Query.filter_by() -筛选关键字表达式。

method sqlalchemy.orm.Query.filter_by(**kwargs)

将给定的筛选条件应用于 Query ,使用关键字表达式。

例如。::

session.query(MyClass).filter_by(name = 'some name')

多个条件可以指定为逗号分隔;其效果是它们将使用 and_() 功能:

session.query(MyClass).\
    filter_by(name = 'some name', id = 5)

关键字表达式是从查询的主实体或作为调用目标的最后一个实体中提取的。 Query.join() .

参见

Query.filter() -筛选SQL表达式。

method sqlalchemy.orm.Query.first()

返回此操作的第一个结果 Query 如果结果不包含任何行,则为“无”。

first()在生成的SQL中应用一个限制,以便在服务器端只生成一个主实体行(注意,如果存在联接加载的集合,则这可能包含多个结果行)。

调用 Query.first() 导致执行基础查询。

method sqlalchemy.orm.Query.from_self(*entities)

返回从此查询的select语句中选择的查询。

1.4 版后已移除: 这个 Query.from_self() 方法在SQLAlchemy的1.x系列中被认为是遗留的,并将在2.0中删除。新的方法是使用 aliased() 与子查询一起构造。参见章节 Selecting from the query itself as a subquery 以2.0迁移说明为例。(SQLAlchemy 2.0的背景: 迁移到Alchemy

Query.from_self() 实际上,将select语句转换为select本身。给出如下查询:

q = session.query(User).filter(User.name.like('e%'))

鉴于 Query.from_self() 版本:

q = session.query(User).filter(User.name.like('e%')).from_self()

此查询呈现为:

SELECT anon_1.user_id AS anon_1_user_id,
       anon_1.user_name AS anon_1_user_name
FROM (SELECT "user".id AS user_id, "user".name AS user_name
FROM "user"
WHERE "user".name LIKE :name_1) AS anon_1

很多情况下 Query.from_self() 可能有用。一个简单的方法是在上面的位置,我们可能希望对查询的用户对象集应用行限制,然后对该行限制集应用其他联接:

q = session.query(User).filter(User.name.like('e%')).\
    limit(5).from_self().\
    join(User.addresses).filter(Address.email.like('q%'))

上面的查询连接到 Address 实体,但仅针对 User 查询:

SELECT anon_1.user_id AS anon_1_user_id,
       anon_1.user_name AS anon_1_user_name
FROM (SELECT "user".id AS user_id, "user".name AS user_name
FROM "user"
WHERE "user".name LIKE :name_1
 LIMIT :param_1) AS anon_1
JOIN address ON anon_1.user_id = address.user_id
WHERE address.email LIKE :email_1

自动混叠

的另一个关键行为 Query.from_self() 它适用于 自动混叠 子查询内的实体(当它们在外部被引用时)。以上,如果我们继续参考 User 实体而不对其应用任何附加别名,则这些引用将使用子查询::

q = session.query(User).filter(User.name.like('e%')).\
    limit(5).from_self().\
    join(User.addresses).filter(Address.email.like('q%')).\
    order_by(User.name)

反对的命令 User.name 别名为内部子查询:

SELECT anon_1.user_id AS anon_1_user_id,
       anon_1.user_name AS anon_1_user_name
FROM (SELECT "user".id AS user_id, "user".name AS user_name
FROM "user"
WHERE "user".name LIKE :name_1
 LIMIT :param_1) AS anon_1
JOIN address ON anon_1.user_id = address.user_id
WHERE address.email LIKE :email_1 ORDER BY anon_1.user_name

自动别名功能仅在 有限的 方法,用于简单的筛选和排序。更野心勃勃的构造(如在联接中引用实体)应该更喜欢使用显式子查询对象,通常使用 Query.subquery() 方法生成显式子查询对象。始终通过查看SQL来测试查询的结构,以确保特定的结构按预期执行!

更改实体

Query.from_self() 还包括修改正在查询的列的功能。在我们的示例中,我们希望 User.id 通过内部查询进行查询,以便我们可以连接到 Address 实体在外部,但我们只希望外部查询返回 Address.email 专栏:

q = session.query(User).filter(User.name.like('e%')).\
    limit(5).from_self(Address.email).\
    join(User.addresses).filter(Address.email.like('q%'))

顺从的:

SELECT address.email AS address_email
FROM (SELECT "user".id AS user_id, "user".name AS user_name
FROM "user"
WHERE "user".name LIKE :name_1
 LIMIT :param_1) AS anon_1
JOIN address ON anon_1.user_id = address.user_id
WHERE address.email LIKE :email_1

Looking out for Inner / Outer Columns

请记住,当引用源自子查询内部的列时,我们需要确保它们存在于子查询本身的columns子句中;这是SQL的一个普通方面。例如,如果我们想从子查询中的已联接实体加载,请使用 contains_eager() ,我们需要添加这些列。下面是一个连接 AddressUser ,然后是子查询,然后我们想要 contains_eager() 访问 User 柱::

q = session.query(Address).join(Address.user).\
    filter(User.name.like('e%'))

q = q.add_entity(User).from_self().\
    options(contains_eager(Address.user))

我们使用 Query.add_entity() 在上面 之前 我们打电话 Query.from_self() 所以 User 列存在于内部子查询中,因此它们可用于 contains_eager() 我们在外部使用的修饰语,产生:

SELECT anon_1.address_id AS anon_1_address_id,
       anon_1.address_email AS anon_1_address_email,
       anon_1.address_user_id AS anon_1_address_user_id,
       anon_1.user_id AS anon_1_user_id,
       anon_1.user_name AS anon_1_user_name
FROM (
    SELECT address.id AS address_id,
    address.email AS address_email,
    address.user_id AS address_user_id,
    "user".id AS user_id,
    "user".name AS user_name
FROM address JOIN "user" ON "user".id = address.user_id
WHERE "user".name LIKE :name_1) AS anon_1

如果我们不打电话 add_entity(User) ,但仍被问到 contains_eager() 加载 User 如果没有正确的联接条件,则将强制在外部添加表-请注意 anon1, "user" 结尾的短语:

-- incorrect query
SELECT anon_1.address_id AS anon_1_address_id,
       anon_1.address_email AS anon_1_address_email,
       anon_1.address_user_id AS anon_1_address_user_id,
       "user".id AS user_id,
       "user".name AS user_name
FROM (
    SELECT address.id AS address_id,
    address.email AS address_email,
    address.user_id AS address_user_id
FROM address JOIN "user" ON "user".id = address.user_id
WHERE "user".name LIKE :name_1) AS anon_1, "user"
参数

*entities -- 将替换所选实体的可选实体列表。

method sqlalchemy.orm.Query.from_statement(statement)

执行给定的select语句并返回结果。

此方法绕过所有内部语句编译,执行语句时不做任何修改。

语句通常是 text()select() 构造,并应返回适用于由此表示的实体类的列集 Query .

参见

使用文本SQL -ORM教程中的用法示例

method sqlalchemy.orm.Query.get(ident)

基于给定的主键标识符返回实例,或 None 如果找不到。

1.4 版后已移除: 这个 Query.get() 方法在SQLAlchemy的1.x系列中被认为是遗留的,在2.0中成为遗留构造。方法现在可用 Session.get() (SQLAlchemy 2.0的背景: 迁移到Alchemy

例如。::

my_user = session.query(User).get(5)

some_object = session.query(VersionedFoo).get((5, 10))

some_object = session.query(VersionedFoo).get(
    {"id": 5, "version_id": 10})

Query.get() 特殊之处在于它可以直接访问拥有者的身份地图 Session . 如果给定的主键标识符存在于本地标识映射中,则该对象将直接从此集合返回,并且不会发出SQL,除非该对象已标记为完全过期。如果不存在,则执行选择以定位对象。

Query.get() 还将执行检查对象是否存在于标识映射中并标记为已过期-将发出选择以刷新对象并确保行仍然存在。如果不是, ObjectDeletedError 提高了。

Query.get() 仅用于返回单个映射实例,而不是多个实例或单个列构造,并且严格使用单个主键值。起源 Query 必须以这种方式构造,即针对一个映射的实体,没有附加的筛选条件。通过加载选项 Query.options() 但可以应用,如果对象尚未在本地存在,则将使用。

参数

ident -- 表示主键的标量、元组或字典。对于复合(例如多列)主键,应传递元组或字典。对于单列主键,标量调用形式通常是最合适的。如果一行的主键是值“5”,则调用看起来像::my_object=query.get(5)tuple表单包含的主键值通常按照它们对应于映射的 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 sqlalchemy.orm.Query.get_execution_options()

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

1.3 新版功能.

attribute sqlalchemy.orm.Query.get_label_style

检索当前标签样式。

1.4 新版功能.

method sqlalchemy.orm.Query.group_by(*clauses)

对查询应用一个或多个groupby条件,并返回新的结果 Query .

可以通过传递来抑制所有现有的分组依据设置 None -这也将通过在映射器上配置来禁止任何组。

参见

以下各节从以下方面描述GROUP BY 2.0 style 调用,但适用于 Query 还有:

使用GROUP BY/HAVING聚合函数 - in the SQLAlchemy 1.4/2.0教程

按标签排序或分组 - in the SQLAlchemy 1.4/2.0教程

method sqlalchemy.orm.Query.having(criterion)

对查询应用HAVING条件并返回新的结果 Query .

Query.having() 与一起使用 Query.group_by() .

有了条件,就可以对诸如count、sum、avg、max和min之类的聚合函数使用过滤器,例如:

q = session.query(User.id).\
            join(User.addresses).\
            group_by(User.id).\
            having(func.count(Address.id) > 2)
method sqlalchemy.orm.Query.instances(result_proxy, context=None)

返回给定 CursorResultQueryContext .

method sqlalchemy.orm.Query.intersect(*q)

针对一个或多个查询生成此查询的交集。

工作方式与 Query.union() . 有关用法示例,请参见该方法。

method sqlalchemy.orm.Query.intersect_all(*q)

生成一个与一个或多个查询相交的所有查询。

工作方式与 Query.union() . 有关用法示例,请参见该方法。

attribute sqlalchemy.orm.Query.is_single_entity

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

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

1.3.11 新版功能.

method sqlalchemy.orm.Query.join(target, *props, **kwargs)

针对此创建SQL联接 Query 对象的标准并生成应用,返回新生成的 Query .

简单关系联接

考虑两个类之间的映射 UserAddress ,有关系 User.addresses 表示的集合 Address 与每个关联的对象 User . 最常见的用法是 Query.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子句”,也就是说,它指示连接的“on”部分应该如何构造。

构造一个连接链,多个 Query.join() 可以使用呼叫。relationship-bound属性同时表示连接的左侧和右侧:

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

注解

如上例所示, 每次调用join()方法的顺序很重要 . 例如,如果我们不能正确地指定 User 然后 Item 然后 Order ,在我们的联接链中;在这种情况下,根据传递的参数,它可能会引发一个不知道如何联接的错误,或者可能产生无效的SQL,在这种情况下,数据库将引发一个错误。在正确的实践中 Query.join() 方法的调用方式与我们希望如何呈现SQL中的JOIN子句一致,并且每个调用都应该表示与它前面的内容之间的清晰链接。

联接到目标实体或可选

第二种形式 Query.join() 允许将任何映射实体或核心可选构造作为目标。在这种用法中, Query.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')

Augmenting Built-in ON Clauses

作为在现有关系条件下提供完整定制的替代品 PropComparator.and_() 函数可以应用于relationship属性,以将附加条件扩充到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

的传统功能查询.join()

1.4 版后已移除: 以下功能已弃用,将在SQLAlchemy 2.0中删除。

这个 Query.join() 方法当前支持几种使用模式和参数,这些模式和参数在SQLAlchemy 1.3中被认为是遗留的。在1.4系列中,以下功能将采用弃用路径:

  • 连接关系名称而不是属性::

    session.query(User).join("addresses")

    为什么是遗产 :字符串名称没有为 Query.join() 始终知道需要什么,特别是没有指示连接的左侧应该是什么。这就产生了像 from_joinpoint 以及将多个连接子句放入一个 Query.join() 不能完全解决问题的呼叫,同时还增加了新的呼叫方式,这是不必要的和昂贵的,以适应内部。

    现代通话模式 :使用实际关系,例如。 User.addresses 在上述情况下:

    session.query(User).join(User.addresses)
  • 自动混叠 aliased=True 旗帜:

    session.query(Node).join(Node.children, aliased=True).\
        filter(Node.name == 'some name')

    为什么是遗产 :的自动混叠功能 Query 无论是在其内部实现还是在其观察到的行为中都非常复杂,几乎从未使用过。通过检查很难知道目标实体的别名在何时何地, Node 在上面的情况下,将被应用,当它不被应用时,另外这个特性必须使用非常精细的启发式来实现这种隐式行为。

    现代通话模式 :使用 aliased() 显式构造:

    from sqlalchemy.orm import aliased
    
    n1 = aliased(Node)
    
    session.query(Node).join(Node.children.of_type(n1)).\
        filter(n1.name == 'some name')
  • 一个调用中的多个联接:

    session.query(User).join("orders", "items")
    
    session.query(User).join(User.orders, Order.items)
    
    session.query(User).join(
        (Order, User.orders),
        (Item, Item.order_id == Order.id)
    )
    
    session.query(User).join(Order, Item)
    
    # ... and several more forms actually

    为什么是遗产 :能够在一次调用中链接多个ON子句 Query.join() 是解决能够指定从哪个实体加入的问题的又一次尝试,并且是各种潜在调用模式的来源,这些模式在内部代价高昂,解析和适应复杂。

    现代通话模式 :在单独的调用中使用关系绑定属性或面向SQL的ON子句,以便每次调用 Query.join() 知道左边应该是什么:

    session.query(User).join(User.orders).join(
        Item, Item.order_id == Order.id)
参数
  • *props -- 的传入参数 Query.join() ,现在使用的props集合应该被视为一个或两个参数的形式,可以是单个“target”实体或ORM属性绑定关系,也可以是目标实体加上“on子句”,它可以是SQL表达式或ORM属性绑定关系。

  • isouter=False -- 如果为true,则使用的联接将是左外部联接,就像 Query.outerjoin() 方法被调用。

  • full=False -- 呈现完整的外部连接;暗示 isouter . …添加的版本:1.1

  • from_joinpoint=False -- 使用时 aliased=True ,此处的设置为True将导致联接来自最近联接的目标,而不是从查询的原始from子句开始。。注意:这个标志被认为是遗留的。

  • aliased=False -- 如果为true,则表示联接目标应匿名别名。后续呼叫 Query.filter() 类似的方法将使传入的条件适应目标别名,直到 Query.reset_joinpoint() 被称为。。注意:这个标志被认为是遗留的。

参见

使用联接查询 在ORM教程中。

映射类继承层次结构 有关如何 Query.join() 用于继承关系。

join() -独立的ORM级联接函数,由内部使用 Query.join() 在以前的SQLAlchemy版本中,它是主要的ORM级联接接口。

method sqlalchemy.orm.Query.label(name)

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

类似于 SelectBase.label() .

attribute sqlalchemy.orm.Query.lazy_loaded_from

InstanceState 用这个吗 Query 对于延迟加载操作。

1.4 版后已移除: 此属性应通过 ORMExecuteState.lazy_loaded_from 属性,在 SessionEvents.do_orm_execute() 事件。

method sqlalchemy.orm.Query.limit(limit)

应用一 LIMIT 到查询并返回新生成的 Query .

method sqlalchemy.orm.Query.merge_result(iterator, load=True)

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

给定由返回的迭代器 Query 对于与此结构相同的结构,返回结果的相同迭代器,所有映射的实例都使用 Session.merge() . 这是一种优化方法,它将合并所有映射的实例,以比调用方法开销更少的方法开销保留结果行和未映射列的结构。 Session.merge() 为每个值显式设置。

结果的结构根据以下列列表确定 Query -如果这些不对应,将发生未选中的错误。

“load”参数与 Session.merge() .

例如如何 Query.merge_result() 使用,请参见示例的源代码 狗堆缓存 在哪里 Query.merge_result() 用于有效地将状态从缓存还原回目标 Session .

method sqlalchemy.orm.Query.offset(offset)

应用一个 OFFSET 到查询并返回新生成的 Query .

method sqlalchemy.orm.Query.one()

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

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

调用 one() 导致执行基础查询。

method sqlalchemy.orm.Query.one_or_none()

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

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

调用 Query.one_or_none() 导致执行基础查询。

1.0.9 新版功能: 补充 Query.one_or_none()

method sqlalchemy.orm.Query.only_return_tuples(value)

当设置为True时,查询结果将始终是元组。

这是专门针对单元素查询的。默认值为False。

1.2.5 新版功能.

method sqlalchemy.orm.Query.options(*args)

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

大多数提供的选项都考虑更改列和关系映射属性的加载方式。

method sqlalchemy.orm.Query.order_by(*clauses)

对查询应用一个或多个ORDER BY条件并返回新的结果 Query .

通过传递可以抑制所有现有的“按顺序排列”设置 None .

参见

以下各节从以下方面介绍ORDER BY 2.0 style 调用,但适用于 Query 还有:

排序依据 - in the SQLAlchemy 1.4/2.0教程

按标签排序或分组 - in the SQLAlchemy 1.4/2.0教程

method sqlalchemy.orm.Query.outerjoin(target, *props, **kwargs)

针对此创建左外部联接 Query 对象的标准并生成应用,返回新生成的 Query .

用法与 join() 方法。

method sqlalchemy.orm.Query.params(*args, **kwargs)

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

可以使用指定参数 * *kwargs, or optionally a single dictionary as the first positional argument. The reason for both is that * *kwargs is convenient, however some parameter dictionaries contain unicode keys in which case * *Kwargs不能使用。

method sqlalchemy.orm.Query.populate_existing()

返回A Query 它将在加载或从当前实例重新使用时过期并刷新所有实例 Session .

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

method sqlalchemy.orm.Query.reset_joinpoint()

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

此方法通常与 aliased=True 特点 Query.join() 方法。请参见中的示例 Query.join() 这是如何使用的。

method sqlalchemy.orm.Query.scalar()

返回第一个结果的第一个元素,如果没有行,则返回无。如果返回多行,则引发multipleResultsFund。

>>> 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

这将导致执行基础查询。

method sqlalchemy.orm.Query.scalar_subquery()

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

类似于 SelectBase.scalar_subquery() .

在 1.4 版更改: 这个 Query.scalar_subquery() 方法替换 Query.as_scalar() 方法。

method sqlalchemy.orm.Query.select_entity_from(from_obj)

设置此的FROM子句 Query 应用它作为对应映射实体的FROM子句的替换。

1.4 版后已移除: 这个 Query.select_entity_from() 方法在SQLAlchemy的1.x系列中被认为是遗留的,并将在2.0中删除。使用 aliased() 而是构造(SQLAlchemy 2.0的背景: 迁移到Alchemy

这个 Query.select_entity_from() 方法为应用 aliased() 在整个查询中显式构造。而不是指 aliased() 显式构造, Query.select_entity_from() 自动地 适应 可选择的目标实体的所有引用。

为…辩护 aliased() 比如选择 User select语句中的对象:

select_stmt = select(User).where(User.id == 7)
user_alias = aliased(User, select_stmt)

q = session.query(user_alias).\
    filter(user_alias.name == 'ed')

上面,我们应用 user_alias 对象在整个查询中显式地。当它不可行时 user_alias 在很多地方都有明确的引用, Query.select_entity_from() 可以在查询开始时使用以适应现有的 User 单位:

q = session.query(User).\
    select_entity_from(select_stmt.subquery()).\
    filter(User.name == 'ed')

上面,生成的SQL将显示 User 实体适用于我们的声明,即使在WHERE条款中:

SELECT anon_1.id AS anon_1_id, anon_1.name AS anon_1_name
FROM (SELECT "user".id AS id, "user".name AS name
FROM "user"
WHERE "user".id = :id_1) AS anon_1
WHERE anon_1.name = :name_1

这个 Query.select_entity_from() 方法类似于 Query.select_from() 方法,其中设置查询的FROM子句。区别在于,它还将自适应应用于引用主实体的查询的其他部分。如果上面我们用过 Query.select_from() 相反,生成的SQL应该是:

-- uses plain select_from(), not select_entity_from()
SELECT "user".id AS user_id, "user".name AS user_name
FROM "user", (SELECT "user".id AS id, "user".name AS name
FROM "user"
WHERE "user".id = :id_1) AS anon_1
WHERE "user".name = :name_1

将文本SQL提供给 Query.select_entity_from() 方法,我们可以利用 text() 构建。然而, text() 构造需要与实体的列对齐,这是通过使用 TextClause.columns() 方法:

text_stmt = text("select id, name from user").columns(
    User.id, User.name).subquery()
q = session.query(User).select_entity_from(text_stmt)

Query.select_entity_from() 本身接受 aliased() 对象,以便 aliased()aliased.adapt_on_names 可在以下范围内使用: Query.select_entity_from() 方法的适应服务。设想一种观点 user_view 同时返回来自的行 user . 如果我们把这个观点 Table ,此视图与 Table 但是,我们可以使用名称匹配从中选择:

user_view = Table('user_view', metadata,
                  autoload_with=engine)
user_view_alias = aliased(
    User, user_view, adapt_on_names=True)
q = session.query(User).\
    select_entity_from(user_view_alias).\
    order_by(User.name)

在 1.1.7 版更改: 这个 Query.select_entity_from() 方法现在接受 aliased() 对象作为 FromClause 对象。

参数

from_obj -- 一 FromClause 将替换此的FROM子句的对象 Query . 它也可能是 aliased() .

method sqlalchemy.orm.Query.select_from(*from_obj)

设置此的FROM子句 Query 明确地。

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 子查询之类的元素。

在 0.9 版更改: 此方法不再将给定的From对象应用于从中选择匹配实体的可选对象;将 select_entity_from() 方法现在可以实现这一点。有关此行为的描述,请参见该方法。

attribute sqlalchemy.orm.Query.selectable

返回 Select 此对象发出的 Query

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

query.enable_eagerloads(False).with_labels().statement
method sqlalchemy.orm.Query.set_label_style(style)

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

指示此查询的 statement 访问器应返回一条select语句,该语句将标签应用于表单中的所有列;这通常用于从具有相同名称的多个表中消除列的歧义。

Query 实际上,发布SQL来加载行,它总是使用列标签。

注解

这个 Query.set_label_style() 方法 only 将以下内容的输出应用于 Query.statement ,以及 not 的任何结果行调用系统 Query 本身,例如 Query.first()Query.all() 等。要使用以下命令执行查询,请执行以下操作 Query.set_label_style() ,调用 Query.statement 使用 Session.execute() ::

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

1.4 新版功能.

method sqlalchemy.orm.Query.slice(start, stop)

计算的“切片” 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)
attribute sqlalchemy.orm.Query.statement

此查询表示的完整select语句。

默认情况下,语句不会将消除歧义的标签应用于构造,除非先调用WITH摼labels(true)。

method sqlalchemy.orm.Query.subquery(name=None, with_labels=False, reduce_columns=False)

返回由该语句表示的完整select语句 Query ,嵌入到 Alias .

查询中的热切联接生成被禁用。

参数
  • name -- 要指定为别名的字符串名称;这将传递给 FromClause.alias() .如果 None ,将在编译时确定地生成名称。

  • with_labels -- 如果属实, with_labels() 将在 Query 首先将表限定标签应用于所有列。

  • reduce_columns -- 如果属实, Select.reduce_columns() 将调用结果 select() 构造,删除相同的命名列,其中一个列还通过外键或WHERE子句等效引用另一个列。

method sqlalchemy.orm.Query.union(*q)

针对一个或多个查询生成此查询的联合。

例如。::

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中调用的查询上呈现order by,除非等要禁用所有order by子句,包括在映射器上配置的子句,请发出 query.order_by(None) -结果 Query 对象不会在其select语句中呈现order by。

method sqlalchemy.orm.Query.union_all(*q)

针对一个或多个查询生成一个联合所有查询。

工作方式与 Query.union() . 有关用法示例,请参见该方法。

method sqlalchemy.orm.Query.update(values, synchronize_session='evaluate', update_args=None)

使用任意WHERE子句执行更新。

更新数据库中与此查询匹配的行。

例如。::

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')

警告

见剖面图 使用任意WHERE子句更新和删除 对于重要的警告和警告,包括对映射器继承配置使用任意更新和删除时的限制。

参数
返回

由数据库的“行数”功能返回的匹配行数。

method sqlalchemy.orm.Query.value(column)

返回与给定列表达式对应的标量结果。

1.4 版后已移除: Query.value() is deprecated and will be removed in a future release. Please use Query.with_entities() in combination with Query.scalar()

method sqlalchemy.orm.Query.values(*columns)

返回一个迭代器,生成与给定列列表对应的结果元组

1.4 版后已移除: Query.values() is deprecated and will be removed in a future release. Please use Query.with_entities()

method sqlalchemy.orm.Query.where(*criterion)

同义词 Query.filter() .

1.4 新版功能.

attribute sqlalchemy.orm.Query.whereclause

返回此查询的当前Where条件的只读属性。

此返回值是SQL表达式构造,或者 None 如果没有建立标准。

method sqlalchemy.orm.Query.with_entities(*entities)

返回一个新的 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)
method sqlalchemy.orm.Query.with_for_update(read=False, nowait=False, of=None, skip_locked=False, key_share=False)

返回一个新的 Query 使用指定的选项 FOR UPDATE 条款。

此方法的行为与 GenerativeSelect.with_for_update() 。在不带参数的情况下调用时,结果 SELECT 语句将具有一个 FOR UPDATE 附加的条款。指定附加参数时,后端特定的选项(如 FOR UPDATE NOWAITLOCK 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

注解

Query.populate_existing() 方法时使用 Query.with_for_update() 方法。目的 Query.populate_existing() 强制将从SELECT读取的所有数据填充到返回的ORM对象中,即使这些对象已经在 identity map .

参见

GenerativeSelect.with_for_update() -核心层面的方法,充分论证和行为描述。

Query.populate_existing() -覆盖已加载到标识映射中的对象的属性。

method sqlalchemy.orm.Query.with_labels()

1.4 版后已移除: 这个 Query.with_labels()Query.apply_labels() 方法被认为是SQLAlChemy 1.x系列的遗留方法,将在2.0中删除。请改用set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)。(有关SQLAlChemy 2.0的背景信息位于: 迁移到Alchemy )

method sqlalchemy.orm.Query.with_parent(instance, property=None, from_entity=None)

添加将给定实例与子对象或集合关联的筛选条件,使用其属性状态和已建立的 relationship() 配置。

1.4 版后已移除: 这个 Query.with_parent() 方法在SQLAlchemy的1.x系列中被认为是遗留的,在2.0中成为遗留构造。使用 with_parent() 独立构造。(SQLAlchemy 2.0的背景: 迁移到Alchemy

该方法使用 with_parent() 函数来生成子句,其结果将传递给 Query.filter() .

参数与 with_parent() ,但给定的属性不能为“无”,在这种情况下,将对该属性执行搜索 Query 对象的目标映射器。

参数
  • instance -- 一个有一些 relationship() .

  • property -- 字符串属性名或类绑定属性,指示应使用来自实例的关系来协调父/子关系。

  • from_entity -- 作为左侧考虑的实体。这默认为 Query 本身。

method sqlalchemy.orm.Query.with_polymorphic(cls_or_mappers, selectable=None, polymorphic_on=None)

为继承类加载列。

1.4 版后已移除: 这个 Query.with_polymorphic() 方法在SQLAlchemy的1.x系列中被认为是遗留的,并将在2.0中删除。使用orm.with_多态性()独立函数(SQLAlchemy 2.0的后台: 迁移到Alchemy

这是一个旧方法,由 with_polymorphic() 功能。

警告

这个 Query.with_polymorphic() 方法可以做到这一点。 not 支持1.4/2.0样式功能,包括 with_loader_criteria() 。请迁移代码以使用 with_polymorphic()

Query.with_polymorphic() 将转换应用于由此表示的“主”映射类 Query . 这里的“主”映射类是指 Query 对象的第一个参数是一个完整类,即 session.query(SomeClass) . 这些转换允许在FROM子句中存在额外的表,以便在查询中提供联接继承子类的列,这既有利于提高加载时间效率,也有利于在查询时使用这些列。

参见

与多态性一起使用 -说明当前模式

method sqlalchemy.orm.Query.with_session(session)

返回A Query 使用给定的 Session .

Query 对象通常使用 Session.query() 方法,建立 Query 不必使用 Session . 这样的 Query 对象,或任何 Query 已经与另一个 Session ,可以产生新的 Query 使用此方法与目标会话关联的对象:

from sqlalchemy.orm import Query

query = Query([MyClass]).filter(MyClass.id == 5)

result = query.with_session(my_session).one()
method sqlalchemy.orm.Query.with_transformation(fn)

返回一个新的 Query 由给定函数转换的对象。

例如。::

def filter_something(criterion):
    def transform(q):
        return q.filter(criterion)
    return transform

q = q.with_transformation(filter_something(x==5))

这允许为 Query 物体。参见中的示例 建筑变压器 .

method sqlalchemy.orm.Query.yield_per(count)

仅产量 count 一次行。

此方法的目的是在获取非常大的结果集(>10000行)时,对子集合中的结果进行批处理并部分生成结果,这样Python解释器就不需要声明非常大的内存区域,这既耗时又会导致内存使用过度。当使用适当的每次设置的收益率(例如大约1000)时,提取数十万行的性能通常会加倍,即使DBAPIS缓冲行(最多)。

从SQLAlChemy 1.4开始, Query.yield_per() 方法等效于使用 yield_per ORM级别的执行选项。请参阅部分 单位产量 有关此选项的更多背景信息,请参阅。

ORM特定的查询构造

Object Name Description

aliased(element[, alias, name, flat, ...])

生成给定元素的别名,通常是 AliasedClass 实例。

AliasedClass

表示用于查询的映射类的“别名”形式。

AliasedInsp

AliasedClass 对象。

Bundle

由返回的一组SQL表达式 Query 在一个命名空间下。

join(left, right[, onclause, isouter, ...])

在左子句和右子句之间生成内部联接。

Load

表示修改 Query 以影响各种映射属性的加载方式。

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, alias=None, name=None, flat=False, adapt_on_names=False)

生成给定元素的别名,通常是 AliasedClass 实例。

例如。::

my_alias = aliased(MyClass)

session.query(MyClass, my_alias).filter(MyClass.id > my_alias.id)

这个 aliased() 函数用于创建映射类到新可选对象的即席映射。默认情况下,从通常映射的可选对象(通常为 Table )使用 FromClause.alias() 方法。然而, aliased() 也可用于将类链接到新的 select() 声明。还有,这个 with_polymorphic() 函数是 aliased() 这是为了指定一个所谓的“多态可选择的”,它对应于同时合并的几个继承子类的联合。

为了方便起见, aliased() 函数也接受普通 FromClause 构造,例如 Tableselect() 构建。在这些情况下, FromClause.alias() 对对象和新的 Alias 返回了对象。归还的人 Alias 在这种情况下不是ORM映射。

使用别名 - in the legacy 对象关系教程(1.x API)

参数
  • element -- 要别名的元素。通常是映射类,但为了方便起见,也可以是 FromClause 元素。

  • alias -- 要将元素映射到的可选单位。这通常用于将对象链接到子查询,并且应该是从 Query.subquery() 方法或 Select.subquery()Select.alias() 方法 select() 构造。

  • name -- 要用于别名的可选字符串名称(如果不是由 alias 参数。除其他外,名称形成了属性名,可以通过由 Query 对象。创建别名时不支持 Join 物体。

  • flat -- 布尔值,将传递给 FromClause.alias() 调用以便 Join 对象将对联接内的各个表进行别名,而不是创建子查询。对于右嵌套联接,这通常由所有现代数据库支持,并且通常生成更高效的查询。

  • adapt_on_names -- 如果为真,则在将ORM实体的映射列映射到给定可选项的列时将使用更自由的“匹配”。如果给定可选项没有对应于实体上的列,则将执行基于名称的匹配。此方法的用例是将实体与某些派生可选项(如使用聚合函数的实体::Class UnitPrice(Base))关联时: __tablename__ ='单价'…Unit_id=column(integer)price=column(numeric)aggregated_unity_price=session.query(func.sum(unit price.price.label('price')).group_by(unit price.unit_id).subquery()aggregated_unity_price=aliased(unit price,alias=aggregated_unity_price,adapt_on_name=true)以上,功能开启 aggregated_unit_price 指的是 .price 将返回 func.sum(UnitPrice.price).label('price') 列,因为它与名称“price”匹配。通常,“price”函数与实际 UnitPrice.price 列,因为它不是原始列的代理。

class sqlalchemy.orm.util.AliasedClass(mapped_class_or_ac, alias=None, name=None, flat=False, adapt_on_names=False, with_polymorphic_mappers=(), with_polymorphic_discriminator=None, base_alias=None, use_mapper_path=False, represents_outer_join=False)

表示用于查询的映射类的“别名”形式。

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 与在原始类上工作的任何属性技术兼容,包括混合属性(请参见 混合属性

这个 AliasedClass 可以检查其基础 Mapper ,别名可选,以及使用 inspect() ::

from sqlalchemy import inspect
my_alias = aliased(MyClass)
insp = inspect(my_alias)

结果检验对象是 AliasedInsp .

class sqlalchemy.orm.util.AliasedInsp(entity, inspected, selectable, name, with_polymorphic_mappers, polymorphic_on, _base_alias, _use_mapper_path, adapt_on_names, represents_outer_join)

AliasedClass 对象。

这个 AliasedInsp 如果给定 AliasedClass 使用 inspect() 功能:

from sqlalchemy import inspect
from sqlalchemy.orm import aliased

my_alias = aliased(MyMappedClass)
insp = inspect(my_alias)

属性对 AliasedInsp 包括:

  • entity - AliasedClass 代表。

  • mapper - Mapper 映射基础类。

  • selectable - Alias 最终表示别名的构造 TableSelect 构造。

  • name -别名的名称。当从返回结果元组时,也用作属性名 Query .

  • with_polymorphic_mappers -收藏 Mapper 对象,指示在 AliasedClass .

  • polymorphic_on -将用作多态加载的“鉴别器”的备用列或SQL表达式。

类签名

class sqlalchemy.orm.AliasedInsp (sqlalchemy.orm.ORMEntityColumnsClauseRole, sqlalchemy.orm.ORMFromClauseRole, sqlalchemy.sql.traversals.MemoizedHasCacheKey, sqlalchemy.orm.base.InspectionAttr)

class sqlalchemy.orm.Bundle(name, *exprs, **kw)

由返回的一组SQL表达式 Query 在一个命名空间下。

这个 Bundle 基本上允许嵌套面向列返回的基于元组的结果 Query 对象。它还可以通过简单的子类化进行扩展,其中重写的主要功能是如何返回表达式集,允许后处理和自定义返回类型,而不涉及ORM标识映射类。

0.9.0 新版功能.

参见

列束

类签名

class sqlalchemy.orm.Bundle (sqlalchemy.orm.ORMColumnsClauseRole, sqlalchemy.sql.annotation.SupportsCloneAnnotations, sqlalchemy.sql.traversals.MemoizedHasCacheKey, sqlalchemy.orm.base.InspectionAttr)

method sqlalchemy.orm.Bundle.__init__(name, *exprs, **kw)

构建新的 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 -- 包的名称。

  • *exprs -- 包含束的列或SQL表达式。

  • single_entity=False -- 如果为真,则为该行 Bundle 可以作为“单个实体”在任何封闭元组之外以与映射实体相同的方式返回。

attribute sqlalchemy.orm.Bundle.c = None

的别名 Bundle.columns .

attribute sqlalchemy.orm.Bundle.columns = None

此引用的SQL表达式的命名空间 Bundle .

例如。::

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 sqlalchemy.orm.Bundle.create_row_processor(query, procs, labels)

为此生成“行处理”函数 Bundle .

可以被子类重写。

参见

列束 -包括子类化的示例。

method sqlalchemy.orm.Bundle.label(name)

提供此的副本 Bundle 传递新标签。

attribute sqlalchemy.orm.Bundle.single_entity = False

如果为true,则对单个绑定的查询将作为单个实体返回,而不是作为键控元组中的元素返回。

class sqlalchemy.orm.Load(entity)

表示修改 Query 以影响各种映射属性的加载方式。

这个 Load 在大多数情况下,当使用类似 joinedload()defer() 或类似。然而, Load 对象也可以直接使用,在某些情况下是有用的。

使用 Load 直接用目标映射类作为参数实例化它。这种用法在处理 Query 有多个实体:

myopt = Load(MyClass).joinedload("widgets")

以上 myopt 现在可用于 Query.options() ,仅对 MyClass 单位:

session.query(MyClass, MyOtherClass).options(myopt)

其中一例 Load 当指定仅对特定类生效的“通配符”选项时,公共API非常有用:

session.query(Order).options(Load(Order).lazyload('*'))

上面,所有关系 Order 将被延迟加载,但这些子对象上的其他属性将使用它们的常规加载策略进行加载。

类签名

class sqlalchemy.orm.Load (sqlalchemy.sql.expression.Generative, sqlalchemy.orm.LoaderOption)

method sqlalchemy.orm.Load.baked_lazyload(attr)

产生新的 Load 对象与 baked_lazyload() 选项应用。

baked_lazyload() 用于示例。

method sqlalchemy.orm.Load.contains_eager(attr, alias=None)

产生新的 Load 对象与 contains_eager() 选项应用。

contains_eager() 用于示例。

method sqlalchemy.orm.Load.defaultload(attr)

产生新的 Load 对象与 defaultload() 选项应用。

defaultload() 用于示例。

method sqlalchemy.orm.Load.defer(key, raiseload=False)

产生新的 Load 对象与 defer() 选项应用。

defer() 用于示例。

method sqlalchemy.orm.Load.immediateload(attr)

产生新的 Load 对象与 immediateload() 选项应用。

immediateload() 用于示例。

method sqlalchemy.orm.Load.joinedload(attr, innerjoin=None)

产生新的 Load 对象与 joinedload() 选项应用。

joinedload() 用于示例。

method sqlalchemy.orm.Load.lazyload(attr)

产生新的 Load 对象与 lazyload() 选项应用。

lazyload() 用于示例。

method sqlalchemy.orm.Load.load_only(*attrs)

产生新的 Load 对象与 load_only() 选项应用。

load_only() 用于示例。

method sqlalchemy.orm.Load.noload(attr)

产生新的 Load 对象与 noload() 选项应用。

noload() 用于示例。

method sqlalchemy.orm.Load.options(*opts)

将一系列选项作为子选项应用于此 Load 对象。

例如。::

query = session.query(Author)
query = query.options(
            joinedload(Author.book).options(
                load_only(Book.summary, Book.excerpt),
                joinedload(Book.citations).options(
                    joinedload(Citation.author)
                )
            )
        )
参数

*opts -- 一系列加载程序选项对象(最终 Load 对象),应应用于 Load 对象。

1.3.6 新版功能.

method sqlalchemy.orm.Load.process_compile_state(compile_state)

对给定的 CompileState .

method sqlalchemy.orm.Load.process_compile_state_replaced_entities(compile_state, mapper_entities)

将修改应用于给定的 CompileState ,给定被替换为WITH_ONLY_COLUMNS()或WITH_ENTITIES()的实体。

1.4.19 新版功能.

method sqlalchemy.orm.Load.raiseload(attr, sql_only=False)

产生新的 Load 对象与 raiseload() 选项应用。

raiseload() 用于示例。

method sqlalchemy.orm.Load.selectin_polymorphic(classes)

产生新的 Load 对象与 selectin_polymorphic() 选项应用。

selectin_polymorphic() 用于示例。

method sqlalchemy.orm.Load.selectinload(attr)

产生新的 Load 对象与 selectinload() 选项应用。

selectinload() 用于示例。

method sqlalchemy.orm.Load.subqueryload(attr)

产生新的 Load 对象与 subqueryload() 选项应用。

subqueryload() 用于示例。

method sqlalchemy.orm.Load.undefer(key)

产生新的 Load 对象与 undefer() 选项应用。

undefer() 用于示例。

method sqlalchemy.orm.Load.undefer_group(name)

产生新的 Load 对象与 undefer_group() 选项应用。

undefer_group() 用于示例。

method sqlalchemy.orm.Load.with_expression(key, expression)

产生新的 Load 对象与 with_expression() 选项应用。

with_expression() 用于示例。

function sqlalchemy.orm.with_loader_criteria(entity_or_base, where_criteria, loader_only=False, include_aliases=False, propagate_to_loaders=True, track_closure_variables=True)

将其他WHERE条件添加到特定实体的所有引用的加载中。

1.4 新版功能.

这个 with_loader_criteria() 选项用于向查询中的特定类型的实体添加限制条件, 全球地 ,这意味着它将应用于在SELECT查询中以及任何子查询、连接条件和关系加载(包括eager和lazy loader)中出现的实体,而无需在查询的任何特定部分指定它。呈现逻辑使用单表继承所使用的相同系统来确保将某个鉴别器应用于表。

E、 g.,使用 2.0-style 查询时,我们可以限制 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筛选条件。

另一个例子,其中过滤将应用于join的ON子句,在这个示例中使用 1.x style 查询:

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() 选项将在给定语句中使用,并且还将自动传播到从此查询派生的所有关系加载。

给出的条件参数是 lambda 它接受一个 cls 论点。给定的类将扩展为包括所有映射的子类,并且本身不必是映射的类。

警告

在调用中使用lambda来 with_loader_criteria() 仅调用 每个唯一类一次 。不应在此lambda内调用自定义函数。看见 使用Lambdas为语句生成添加显著的速度增益 获取“lambda SQL”特性的概述,该特性仅供高级使用。

参数
  • entity_or_base -- 一个映射类,或者是一组特定映射类的超类,该规则将应用于该类。

  • where_criteria -- 应用限制条件的核心SQL表达式。这也可能是一个“lambda:”或Python函数,当给定的类是具有许多不同映射子类的基时,它接受目标类作为参数。

  • include_aliases -- 如果为True,则将规则应用于 aliased() 构造。

  • propagate_to_loaders -- 默认为True,应用于关系加载器,如lazy loader。

参见

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, right, onclause=None, isouter=False, full=False, join_to_left=None)

在左子句和右子句之间生成内部联接。

join() 是由提供的核心联接接口的扩展 join() ,其中,左和右可选择项可能不仅是核心可选择对象,例如 Table ,但也映射类或 AliasedClass 实例。“on”子句可以是SQL表达式,也可以是引用已配置的 relationship() .

join() 在现代使用中并不常用,因为它的功能封装在 Query.join() 方法,它的特点是在 join() 独自一人。明确使用 join() 具有 Query 涉及使用 Query.select_from() 方法,如:

from sqlalchemy.orm import join
session.query(User).\
    select_from(join(User, Address, User.addresses)).\
    filter(Address.email_address=='foo@bar.com')

在现代的SQLAlchemy中,上面的连接可以更简洁地写为:

session.query(User).\
        join(User.addresses).\
        filter(Address.email_address=='foo@bar.com')

Query.join() 有关ORM级联接的现代用法的信息。

0.8 版后已移除: 这个 join_to_left 参数已弃用,将在将来的版本中删除。参数无效。

function sqlalchemy.orm.outerjoin(left, right, onclause=None, full=False, join_to_left=None)

在左子句和右子句之间生成左外部联接。

这是“外部联接”版本的 join() 函数,除了生成一个外部联接之外,它具有相同的行为。有关其他用法的详细信息,请参阅该函数的文档。

function sqlalchemy.orm.with_parent(instance, prop, from_entity=None)

使用已建立的筛选条件,创建将此查询的主实体与给定的相关实例关联的筛选条件 relationship() 配置。

例如。::

stmt = select(Address).where(with_parent(some_user, Address.user))

呈现的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 -- 字符串属性名或类绑定属性,它指示应使用实例中的哪个关系来协调父/子关系。。已弃用::不推荐使用字符串的1.4,它将在SQLAlchemy 2.0中删除。请直接使用类绑定属性。

  • from_entity -- 作为左侧考虑的实体。这默认为 Query 本身。…添加的版本:1.2

Previous: 构造函数和对象初始化 Next: 使用会话