Метод distinct класса Query
Метод distinct класса Query
добавляет в SQL-запрос оператор DISTINCT.
Он заставляет базу данных вернуть только уникальные
строки, отбрасывая повторяющиеся комбинации значений
в выбранных столбцах. Метод не принимает обязательных
параметров и возвращает новый объект Query,
поэтому его удобно объединять в цепочку с другими
методами, например filter, order_by
или count.
Синтаксис
Query.distinct(*expr)
Пример
Давайте создадим модель статьи и добавим несколько записей с повторяющимися статусами:
from sqlalchemy import create_engine, String
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] = mapped_column(String(50))
status: Mapped[str] = mapped_column(String(20))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', status='draft'),
Article(title='article 2', status='draft'),
Article(title='article 3', status='published'),
Article(title='article 4', status='published'),
])
session.commit()
Пример
Теперь выберем уникальные значения столбца status
с помощью метода distinct и метода
with_entities:
from sqlalchemy import create_engine, String
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] = mapped_column(String(50))
status: Mapped[str] = mapped_column(String(20))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', status='draft'),
Article(title='article 2', status='draft'),
Article(title='article 3', status='published'),
Article(title='article 4', status='published'),
])
session.commit()
res = session.query(Article.status).distinct().all()
print(res)
Результат выполнения кода:
[('draft',), ('published',)]
Пример
Метод distinct можно комбинировать с методом
order_by,
чтобы получить отсортированный список уникальных значений:
from sqlalchemy import create_engine, String
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] = mapped_column(String(50))
status: Mapped[str] = mapped_column(String(20))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', status='draft'),
Article(title='article 2', status='draft'),
Article(title='article 3', status='published'),
Article(title='article 4', status='published'),
])
session.commit()
res = session.query(Article.status).distinct().order_by(Article.status.desc()).all()
print(res)
Результат выполнения кода:
[('published',), ('draft',)]
Пример
Также метод distinct работает совместно
с методом count,
чтобы посчитать количество уникальных строк:
from sqlalchemy import create_engine, String
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] = mapped_column(String(50))
status: Mapped[str] = mapped_column(String(20))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', status='draft'),
Article(title='article 2', status='draft'),
Article(title='article 3', status='published'),
Article(title='article 4', status='published'),
])
session.commit()
res = session.query(Article.status).distinct().count()
print(res)
Результат выполнения кода:
2
Итоговый SQL запрос:
SELECT count(*) AS count_1 FROM (SELECT DISTINCT articles.status AS status FROM articles) AS anon_1
Смотрите также
-
класс
Query,
который представляет ORM-запрос -
метод
group_by,
который группирует строки по столбцу -
метод
with_entities,
который выбирает нужные столбцы -
метод
count,
который считает количество строк