Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Python: sqlalchemy, pagination, streaming

Как в SQLAlchemy корректно и эффективно получать большие объемы данных из базы данных

Этот вопрос проверяет, понимаешь ли ты, как читать много данных без перегрузки памяти и лишней нагрузки на БД.

Короткий ответ

Большие объемы данных нельзя «просто загрузить в список», потому что это быстро съедает память и замедляет приложение. Обычно применяют постраничное чтение (pagination) или потоковую обработку (streaming), чтобы брать данные частями. В SQLAlchemy для этого используют limit/offset, курсорную пагинацию (по стабильному ключу), а также итерацию результата, чтобы не держать всё в памяти. Дополнительно важно выбирать только нужные колонки и отключать лишние ORM-навороты, если они не нужны.

Длинный ответ

Когда данных много, главная цель — не тащить всё сразу в память и не заставлять БД делать тяжёлую работу без необходимости. Ниже — основные практики, которые дают результат в реальных проектах.

Определение

Bulk fetch — получение большого набора строк из БД, при котором важно контролировать объем данных в памяти и способ чтения результата.

1) Выбирать меньше данных

Даже без пагинации можно сильно снизить нагрузку, если не забирать лишнее.

  • Выбирай только нужные колонки через select(User.id, User.email) вместо select(User).

  • Если нужна только часть объекта, используй «тонкие» выборки, а не полноценную загрузку всех полей.

from sqlalchemy import select

stmt = select(User.id, User.email).where(User.is_active == True)
rows = session.execute(stmt).all()  # всё ещё может быть много, но данных меньше

2) Читать частями: пагинация

Есть два основных подхода.

2.1) Offset/Limit пагинация

Подходит для небольших/средних объёмов и простых админок, но на больших таблицах offset может становиться медленным.

page_size = 1000
page = 0

stmt = select(User).order_by(User.id).limit(page_size).offset(page * page_size)
users = session.execute(stmt).scalars().all()

Минусы:

  • Большой offset часто ухудшает скорость (БД всё равно «пропускает» много строк).

2.2) Курсорная пагинация (keyset pagination)

Это обычно лучший вариант для больших таблиц.

Идея: вместо offset используем «последний увиденный ключ», например id.

from sqlalchemy import select

page_size = 1000
last_id = 0

stmt = (
    select(User)
    .where(User.id > last_id)
    .order_by(User.id)
    .limit(page_size)
)

users = session.execute(stmt).scalars().all()
# last_id обновляем на max(User.id) из текущей порции

Плюсы:

  • Лучше масштабируется на больших объёмах.

  • Стабильнее по производительности.

3) Потоковая обработка вместо all()

Если тебе не нужен список целиком, лучше обрабатывать результаты по мере чтения.

Пример: обработка «строка за строкой» (без .all()):

stmt = select(User).order_by(User.id)

for user in session.execute(stmt).scalars():
    # обработка одной записи
    handle(user)

Практический момент:

  • Это снижает память приложения, но всё равно важно следить за тем, как ORM кеширует объекты в session.

4) Контроль памяти ORM-сессии

Если ты грузишь много ORM-объектов, сессия может копить их в identity map.

Типичные приемы:

  • Обрабатывать порциями и делать session.expunge_all()/session.clear() (в зависимости от стека и версии), чтобы не держать тысячи объектов.

  • Если не нужно изменять объекты — иногда проще читать «сырьём» (columns/rows), а не ORM-сущностями.

stmt = select(User.id, User.email).order_by(User.id)

for row in session.execute(stmt):
    user_id, email = row
    handle(user_id, email)

Вывод

Большие выборки в SQLAlchemy стоит строить так: минимум колонок, чтение частями (лучше keyset) и без загрузки всего в память через .all(), особенно если результаты можно обрабатывать потоком.

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Python

    Python

Ключевые слова

#sqlalchemy

#pagination

#streaming

Подпишись на Python Developer в телеграм

  • Аватар

    Python Guru

    Sergey Filichkin

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.