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()`