【发布时间】:2018-10-08 18:33:55
【问题描述】:
我想要
DBSession.query(Article).group_by(Article.created.month).all()
但是这个查询不能使用
如何使用 SQLAlchemy 做到这一点?
【问题讨论】:
标签: python sqlalchemy
我想要
DBSession.query(Article).group_by(Article.created.month).all()
但是这个查询不能使用
如何使用 SQLAlchemy 做到这一点?
【问题讨论】:
标签: python sqlalchemy
假设你的db引擎确实支持MONTH()这样的功能,你可以试试
import sqlalchemy as sa
DBSession.query(Article).group_by( sa.func.year(Article.created), sa.func.month(Article.created)).all()
否则你可以在 python 中分组
from itertools import groupby
def grouper( item ):
return item.created.year, item.created.month
for ( (year, month), items ) in groupby( query_result, grouper ):
for item in items:
# do stuff
【讨论】:
我知道这个问题很古老,但为了任何寻找解决方案的人的利益,这是不支持像 MONTH() 这样的函数的数据库的另一种策略:
db.session.query(sa.func.count(Article.id)).\
group_by(sa.func.strftime("%Y-%m-%d", Article.created)).all()
本质上,这是将时间戳转换为可以分组的截断字符串。
如果您只想要最近的条目,您可以添加,例如:
order_by(Article.created.desc()).limit(7)
按照此策略,您只需省略年份和月份即可轻松创建分组,例如星期几。
【讨论】:
date_trunc 而不是 strftime
THC4k 答案有效,但我只想补充一点,query_result 需要已经排序才能让 itertools.groupby 按您想要的方式工作。
query_result = DBSession.query(Article).order_by(Article.created).all()
这里是itertools.groupby docs中的解释:
groupby() 的操作类似于 Unix 中的 uniq 过滤器。每次键函数的值发生变化时,它都会生成一个中断或新组(这就是为什么通常需要使用相同的键函数对数据进行排序的原因)。这种行为与 SQL 的 GROUP BY 不同,后者聚合公共元素而不管其输入顺序如何。
【讨论】: