Метод group_by
Метод group_by класса Query выполняет
группировку строк результирующего набора по одному
или нескольким столбцам. Он соответствует оператору
GROUP BY языка SQL. Первым параметром метод
принимает столбец или список столбцов, по которым
нужно сгруппировать записи.
Синтаксис
Query.group_by(*entities)
Пример
Давайте создадим модель статьи и сгруппируем
записи по столбцу status, посчитав количество
статей в каждой группе:
from sqlalchemy import create_engine, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', text='text 1', status='published', num=1),
Article(title='article 2', text='text 2', status='published', num=2),
Article(title='article 3', text='text 3', status='draft', num=3),
])
session.commit()
res = session.query(
Article.status,
func.count(Article.id)
).group_by(Article.status).all()
print(res)
Результат выполнения кода:
[('draft', 1), ('published', 2)]
Пример
Давайте сгруппируем статьи по двум столбцам
status и num, а также посчитаем сумму
значений в каждой группе:
from sqlalchemy import create_engine, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', text='text 1', status='published', num=1),
Article(title='article 2', text='text 2', status='published', num=1),
Article(title='article 3', text='text 3', status='draft', num=2),
])
session.commit()
res = session.query(
Article.status,
Article.num,
func.count(Article.id)
).group_by(Article.status, Article.num).all()
print(res)
Результат выполнения кода:
[('draft', 2, 1), ('published', 1, 2)]
Пример
Давайте посмотрим, какой SQL-запрос формируется
при использовании метода group_by:
from sqlalchemy import create_engine, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
query = session.query(
Article.status,
func.count(Article.id)
).group_by(Article.status)
print(query)
Итоговый SQL запрос:
SELECT articles.status AS articles_status, count(articles.id) AS count_1
FROM articles GROUP BY articles.status