SQLAlchemy1.4ORM中Query.count的等价物是什么?

给定一个像这样的 SQLAlchemy ORM 模型

class Foo(Base):
    __tablename__ = 'foo'

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String())

在 SQLAlchemy 1.4 / 2.0 中,ORM 的session.query习惯用法正在与 SQLAlchemy 核心select函数*统一,因此要获取所有Foo我们会做的

foos = session.execute(Foo).scalars().all()

代替

foos = session.query(Foo).all()

在当前 (sqlalchemy<=1.3) ORM 中,我们可以Foo通过以下查询获取数据库中s的数量:

nfoos = session.query(Foo).count()

但是我们如何在 SQLALchemy 1.4 中获得计数呢?

session.execute(sa.select(Foo).count())

加注

AttributeError: 'Select' 对象没有属性 'count'

session.execute(sa.select(Foo)).count()

加注

AttributeError: 'ChunkedIteratorResult' 对象没有属性 'count'

session.execute(sa.select(sa.func.count(Foo)))

加注

sqlalchemy.exc.ArgumentError: SQL 表达式元素预期,得到<class '__main__.Foo'>

这有效,

session.execute(sa.select(sa.func.count(Foo.id))).scalars()

但是指定一个属性似乎没有Query.count版本那么 OO / 优雅。此外,它排除了构建查询但推迟决定是检索计数还是模型实例的可能性。

count()在新的 SQLAlchemy 1.4 世界中获取ORM 查询的惯用方法是什么?


* session.query()API 仍可在 1.4 及更高版本中使用

回答

根据Ilja Everilä的评论,似乎在 SQLAlchemy 1.4 中发布的新 ORM 查询 API(在撰写本文时处于测试阶段)中没有与Query.count直接等效的内容。

等效的功能是调用count(),从子查询中选择*

from sqlalchemy import func, select

count = (
    session.execute(select(func.count()).select_from(select(Foo).subquery()))
    .scalars()
    .one()
)

生成此 SQL

SELECT count(*) AS count_1 
 FROM (SELECT foo.id AS id, foo.name AS name 
         FROM foo) 
AS anon_1

计算一个属性,例如主键列,生成一个简单的 SELECT COUNT

count = session.execute(select(func.count(Foo.id))).scalars().one()
SELECT count(foo.id) AS count_1 
FROM foo

Query.count 在 1.4 中仍然受支持,因此它仍然可以使用,就像 1.3 中可用的所有 ORM 功能一样。


*Query.count 也从子查询中选择而不是SELECT COUNT直接执行。

  • Very darn complicated for such a basic operation! `db.session.execute(
    sa.select(sa.func.count(some_previous_stmt.froms[0].c.id))
    ).scalar()`

以上是SQLAlchemy1.4ORM中Query.count的等价物是什么?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>