⚖️ Старый vs Новый: session.query() vs select()

Из лекции (Legacy API) → современный стиль SQLAlchemy 2.x

⚡ Главное отличие

В лекции используется session.query() — это Legacy Query API (работает во всех версиях SQLAlchemy). SQLAlchemy 2.x рекомендует select() + session.execute().

  • Старый: session.query(User).filter(User.age > 20).all()
  • Новый: session.execute(select(User).where(User.age > 20)).scalars().all()
  • Оба варианта работают в SQLAlchemy 2.x — session.query() не удалён, просто помечен как legacy.

Почему два стиля?

В SQLAlchemy 1.x единственным способом читать данные был session.query(). В версии 2.0 появился новый унифицированный API на основе select(). Лекция практикума написана на старом стиле — он полностью совместим с 2.x, но новые проекты рекомендуется писать на select().

Задачи практикума используют session.query() — это нормально. Старый API не удалён и работает. Современный стиль показан ниже для понимания.

Сравнение подходов

1. Чтение всех записей

Из лекции (старое):

# Legacy Query API
users = session.query(User).all()

Современное (SQLAlchemy 2.x):

from sqlalchemy import select
users = session.execute(select(User)).scalars().all()

2. Фильтрация

Из лекции (старое):

# .filter() с атрибутом модели
user = session.query(User).filter(User.name == "Alice").first()

Современное:

from sqlalchemy import select
user = session.execute(
    select(User).where(User.name == "Alice")
).scalar_one_or_none()

3. Агрегации

Из лекции (старое):

from sqlalchemy import func
avg = session.query(func.avg(User.age)).scalar()

Современное:

from sqlalchemy import select, func
avg = session.execute(
    select(func.avg(User.age))
).scalar()

4. JOIN

Из лекции (старое):

rows = (
    session.query(User.name, Address.description)
    .join(User.addresses)
    .all()
)

Современное:

from sqlalchemy import select
rows = session.execute(
    select(User.name, Address.description)
    .join(User.addresses)
).all()

5. Проверка существования

Из лекции (старое):

exists = session.query(
    session.query(User)
    .filter_by(name="Charlie")
    .exists()
).scalar()

Современное:

from sqlalchemy import select, exists as sa_exists
stmt = sa_exists(select(User).where(User.name == "Charlie"))
result = session.execute(select(stmt)).scalar()

Итог: когда что использовать

Ситуация Рекомендация
Учебные задачи практикума session.query() — как в лекции
Новый рабочий проект select() + session.execute()
Поддержка legacy-кода Оставить session.query() — он работает