【问题标题】:SQLAlchemy Sum after Group by Minute按分钟分组后的 SQLAlchemy 总和
【发布时间】:2021-09-30 07:40:23
【问题描述】:

我正在使用 SQLAlchemy,需要聚合一个 PostgreSQL 表 scores,这样每一行都包含 1 分钟内所有 points 的总和。

但是,我在下面的尝试导致错误失败。我们如何按 1 分钟时间段进行分组?

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedFunction) 函数日(整数)不存在 第 2 行:从分数 GROUP BY 天(scores.timestamp),小时(scores.time... ^ 提示:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer
from sqlalchemy.sql import func
from db import postgres_session, postgres_engine

from models.Base import Base

class Score(Base):
    __tablename__ = "scores"

    timestamp = Column(Integer, primary_key=True)
    points = Column(Integer)


# Create table and add some rows
Base.metadata.create_all(postgres_engine)
# 6:45:xx AM GMT
postgres_session.add(Score(timestamp=1625985956, points=1))
postgres_session.add(Score(timestamp=1625985957, points=2))
postgres_session.add(Score(timestamp=1625985958, points=3))
postgres_session.add(Score(timestamp=1625985959, points=4))
# 6:46:xx AM GMT
postgres_session.add(Score(timestamp=1625985960, points=10))
postgres_session.add(Score(timestamp=1625985961, points=20))
postgres_session.add(Score(timestamp=1625985962, points=30))
# 7:02:xx AM GMT
postgres_session.add(Score(timestamp=1625986960, points=10))
postgres_session.add(Score(timestamp=1625986961, points=20))
postgres_session.add(Score(timestamp=1625986962, points=30))
postgres_session.commit()

agg = (
    postgres_session.query(func.max(Score.points).label('points'))
    .group_by(
        func.day(Score.timestamp),
        func.hour(Score.timestamp),
        func.minute(Score.timestamp),
    )
    .all()
)

for a in agg:
    print(a.timestamp, a.points)  # print out the minute timestamp and sum of points within that minute

第二次尝试:

agg = (
    postgres_session.query(func.max(Score.points).label("points"))
    .group_by(
        func.floor(Score.timestamp / 60) * 60,
    )
    .all()
)

错误:

  File "/home/ubuntu/foo/test.py", line 43, in <module>
    a.timestamp, a.points
AttributeError: Could not locate column in row for column 'timestamp'

【问题讨论】:

    标签: python database postgresql sqlalchemy aggregate


    【解决方案1】:

    GROUP BY 子句中使用的条件必须存在于SELECT 子句中,因此您需要将它们添加到您的查询中。正如第一条错误消息所述,没有与您的用法相匹配的 date 函数 - 您想使用 date_partextract (docs)。

    此查询在其SELECT 子句中定义按列分组,并引用GROUP BY 中的标签。

    agg = (
        postgres_session.query(
            func.date_part('day', func.to_timestamp(Score.timestamp)).label('day'),
            func.date_part('hour', func.to_timestamp(Score.timestamp)).label('hour'),
            func.date_part('minute', func.to_timestamp(Score.timestamp)).label('minute'),
    
            func.max(Score.points).label('points'))
        .group_by(
            'day', 'hour', 'minute'
        )
        .all()
    )
    
    for a in agg:
        print(a.day, a.hour, a.minute, a.points)
    

    产生这个输出

    11.0 6.0 45.0 4
    11.0 7.0 2.0 30
    11.0 6.0 46.0 30
    

    【讨论】:

      猜你喜欢
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      • 2015-06-13
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      相关资源
      最近更新 更多