SQLAlchemy 在时间戳列中按天分组
Posted
技术标签:
【中文标题】SQLAlchemy 在时间戳列中按天分组【英文标题】:SQLAlchemy group by day in timestamp column 【发布时间】:2022-01-16 19:45:10 【问题描述】:我在 SQLAlchemy 中定义了一个 ORM(模型),如下所示:
class StoreView(Base):
__tablename__ = 'store_views'
id = Column(Integer, primary_key=True)
store_id = Column(Integer)
started_from = Column(TIMESTAMP)
end_to = Column(TIMESTAMP)
average_watch_time = Column(Float)
total_watch_time = Column(Float)
total_views = Column(Float)
我计划获取每天所有视图的总和,并尝试根据它们的 end_to 对结果进行分组。我在 sqlalchemy 中使用了以下查询:
result = session.query(
StoreView
).filter(
StoreView.started_from > from_date,
StoreView.end_to < to_date,
StoreView.store_id==5
).group_by( sa.func.year(StoreView.end_to), sa.func.month(StoreView.end_to)).all()
但是这个查询会抛出这个错误:
(psycopg2.errors.UndefinedFunction) function year(timestamp without time zone) does not exist
HINT: No function matches the given name and argument types. You may need to add explicit type casts.
我在我的模型中使用时间戳,但由于某种原因我不打算更改它。我唯一能做的就是修改查询。 SQLAlchemy 已连接到 AWS Redshift。
【问题讨论】:
【参考方案1】:如果您想在 Postgresql 中按每天的查看次数进行分组,查询将如下所示(省略WHERE
子句):
SELECT end_to::date AS date, COUNT(*) AS views
FROM store_views
GROUP BY end_to::date
ORDER BY date DESC;
处理时间戳的技巧是将其转换为日期类型,这会将值截断为日期部分。在 SQLAlchemy 中,等效代码是
with Session() as s:
result = s.query(
sa.cast(StoreView.end_to, sa.Date).label('date'),
sa.func.count().label('views'),
).filter(
).group_by(
sa.cast(StoreView.end_to, sa.Date),
).order_by(
sa.text('date desc')
)
for row in result:
print(row)
产生类似的值
(datetime.date(2021, 5, 4), 1)
(datetime.date(2021, 5, 3), 1)
(datetime.date(2021, 5, 2), 2)
...
等效的 SQLAlchemy 2.0 样式查询将是
with Session() as s:
q = sa.select(
sa.cast(StoreView.end_to, sa.Date).label('date'),
sa.func.count().label('views'),
).where(
StoreView.started_from > from_date,
StoreView.end_to < to_date,
StoreView.store_id == 5,
).group_by(
sa.cast(StoreView.end_to, sa.Date),
).order_by(
sa.text('date desc')
)
result = s.execute(q)
【讨论】:
以上是关于SQLAlchemy 在时间戳列中按天分组的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Postgres 在 Rails 中按天对记录进行分组
如何使用 SQL Server 在此查询中按天对结果进行分组?