Группа по годам, месяцам, дням в sqlalchemy

Я хочу "DBSession.query(статья).group_by (Article.created.month).all()"

Но этот запрос не может использовать

Как это сделать с помощью SQLAlchemy?

Ответ 1

Предполагая, что ваш db-движок действительно поддерживает такие функции, как MONTH(), вы можете попробовать

import sqlalchemy as sa
DBSession.query(Article).group_by( sa.func.year(Article.created), sa.func.month(Article.created)).all()

else вы можете группировать в 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

Ответ 2

Ответ THC4k работает, но я просто хочу добавить, что query_result должен быть уже отсортирован, чтобы получить itertools.groupby, работая так, как вы хотите.

query_result = DBSession.query(Article).order_by(Article.created).all()

Вот объяснение в itertools.groupby docs:

Операция groupby() похожа на uniq-фильтр в Unix. Он генерирует разрыв или новую группу каждый раз, когда изменяется значение ключевой функции (поэтому, как правило, необходимо сортировать данные с использованием одной и той же ключевой функции). Это поведение отличается от SQLs GROUP BY, которое объединяет общие элементы независимо от их порядка ввода.

Ответ 3

Я знаю, что этот вопрос древний, но в интересах любого, кто ищет решения, вот еще одна стратегия для баз данных, которые не поддерживают такие функции, как 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)

Следуя этой стратегии, вы можете легко создавать группы, такие как день недели, просто опуская год и месяц.