【问题标题】:Using COUNT(*) OVER() in current query with SQLAlchemy over PostgreSQL在 SQLAlchemy over PostgreSQL 的当前查询中使用 COUNT(*) OVER()
【发布时间】:2019-02-08 05:43:21
【问题描述】:

在使用 Python 和 SQLAlchemy 和 PostgreSQL 数据库的原型应用程序中,我有以下架构(摘录):

class Guest(Base):
    __tablename__ = 'guest'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    surname = Column(String(50))
    email = Column(String(255))
    [..]
    deleted = Column(Date, default=None)

我想使用 SQLAlchemy 构建一个查询,用于检索来宾列表,以显示在后台。

为了实现分页,我将使用 LIMIT 和 OFFSET,以及 COUNT(*) OVER() 来获取执行查询时的记录总数(而不是使用不同的查询)。

SQL 查询的一个示例可能是:

  SELECT id, name, surname, email,
       COUNT(*) OVER() AS total
    FROM guest
   WHERE (deleted IS NULL)
ORDER BY id ASC
   LIMIT 50
  OFFSET 0

如果我要使用 SQLAlchemy 构建查询,我可以执行以下操作:

query = session.query(Guest)
query = query.filter(Login.deleted == None)
query = query.order_by(Guest.id.asc())
query = query.offset(0)
query = query.limit(50)
result = query.all()

如果我想计算来宾表中的所有行,我可以这样做:

from sqlalchemy import func
query = session.query(func.count(Guest.id))
query = query.filter(Login.deleted == None)
result = query.scalar()

现在我要问的问题是如何使用 SQLAlchemy 执行一个查询,类似于上面的那个,用一块石头杀死两只鸟(返回前 50 行和总行数以构建分页链接,一站式查询)。

有趣的一点是window functions in PostgreSQL 的使用允许上述行为,从而使您不必查询两次而只需一次。

有可能吗?

提前致谢。

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    所以我在 SQLAlchemy 文档中找不到任何示例,但我找到了这些函数:

    我设法将它们结合起来,以产生我正在寻找的结果:

    from sqlalchemy import func
    query = session.query(Guest, func.count(Guest.id).over().label('total'))
    query = query.filter(Guest.deleted == None)
    query = query.order_by(Guest.id.asc())
    query = query.offset(0)
    query = query.limit(50)
    result = query.all()
    

    干杯!

    附:我还发现了这个question on Stack Overflow,但没有得到答复。

    【讨论】:

      猜你喜欢
      • 2017-04-04
      • 2020-12-08
      • 2021-07-04
      • 2021-01-08
      • 2016-07-29
      • 1970-01-01
      • 2022-12-02
      • 2017-09-22
      • 1970-01-01
      相关资源
      最近更新 更多