在一个sqlalchemy中按年,月,日分组

gam*_*amp 15 python sqlalchemy

我想要

DBSession.query(Article).group_by(Article.created.month).all()
Run Code Online (Sandbox Code Playgroud)

但是这个查询无法使用

我如何使用SQLAlchemy执行此操作?

Joc*_*zel 32

假设您的db引擎实际上支持类似的功能MONTH(),您可以尝试

import sqlalchemy as sa
DBSession.query(Article).group_by( sa.func.year(Article.created), sa.func.month(Article.created)).all()
Run Code Online (Sandbox Code Playgroud)

否则你可以在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
Run Code Online (Sandbox Code Playgroud)


Mat*_*att 10

我知道这个问题很古老,但为了任何寻求解决方案的人的利益,这是不支持 MONTH() 等函数的数据库的另一种策略:

db.session.query(sa.func.count(Article.id)).\
    group_by(sa.func.strftime("%Y-%m-%d", Article.created)).all()
Run Code Online (Sandbox Code Playgroud)

本质上,这是将时间戳转换为截断的字符串,然后可以对其进行分组。

如果您只想要最近的条目,您可以添加,例如:

    order_by(Article.created.desc()).limit(7)
Run Code Online (Sandbox Code Playgroud)

遵循此策略,您只需省略年和月即可轻松创建诸如星期几之类的分组。

  • 对于 postgres 使用“date_trunc”而不是“strftime” (4认同)

rab*_*ben 9

THC4k的答案有效,但我只是想补充一下这个query_result需要已经排序,以便itertools.groupby按照你想要的方式工作.

query_result = DBSession.query(Article).order_by(Article.created).all()
Run Code Online (Sandbox Code Playgroud)

这是itertools.groupby文档中的解释 :

groupby()的操作类似于Unix中的uniq过滤器.每次键函数的值发生变化时,它都会生成一个中断或新组(这就是为什么通常需要使用相同的键函数对数据进行排序).这种行为不同于SQL的GROUP BY,它聚合了常见元素而不管它们的输入顺序如何.