在PostgreSQL上通过SQLAlchemy在当前查询中使用COUNT(*)OVER()

时间:2018-09-03 07:37:26

标签: python postgresql sqlalchemy

在将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可以实现上述行为,从而使您不必查询两次,而只需查询一次。

有可能吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

所以我在SQLAlchemy文档中找不到任何示例,但是我找到了以下功能:

  • [count()][1]
  • [over()][1]
  • [label()][1]

我设法将它们结合起来,以产生出我一直想要的结果:

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

干杯!

P.S。我还发现了这个question on Stack Overflow,但未得到答复。