SQLAlchemy 在时间戳列中按天分组
SQLAlchemy group by day in timestamp column
我在 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。
如果您想在 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 中定义了一个 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。
如果您想在 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)