Как ответить
Да, в проекте использовалась ORM-библиотека. Конкретно — SQLAlchemy для Python. Основная причина выбора была в том, что проект стартовал с PostgreSQL, но в будущем планировался переход на MySQL для одного из клиентов. ORM позволила абстрагироваться от диалекта БД и писать бизнес-логику без привязки к конкретной СУБД.
На практике ORM использовалась для 90% операций: CRUD, миграции (Alembic), построение базовых запросов с фильтрацией и пагинацией. Например, типичный код выглядел так:
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False)
email = Column(String(120), unique=True)Этот класс маппился на таблицу users, и все операции шли через сессию: session.query(User).filter(User.name == 'Иван').all(). Для сложных запросов — например, отчёт с агрегацией по датам с джойном трёх таблиц — мы писали сырой SQL через text(), потому что ORM-цепочки становились нечитаемыми и тормозили. Я помню случай, когда запрос на выборку топ-10 пользователей по сумме заказов через ORM выполнялся 2 секунды, а тот же запрос на чистом SQL — 200 миллисекунд. Тогда мы заменили его на session.execute(text("...")).
Из проблем: N+1 запросов. Когда мы выводили список заказов и для каждого заказа подтягивали пользователя, ORM делала отдельный запрос на каждую строку. Решили через joinedload() — это загружало связанные данные одним join'ом. Ещё была сложность с миграциями: Alembic иногда генерировал неверные типы колонок (например, вместо VARCHAR(255) ставил VARCHAR(50)), приходилось править вручную.
В итоге ORM оправдала себя для простых операций и прототипирования, но для сложной отчётности и высоконагруженных мест мы писали SQL напрямую. Мой вывод: ORM — это инструмент для ускорения разработки, но не серебряная пуля. Джуниору стоит понимать, что под капотом — какие запросы генерирует ORM, и уметь писать их вручную, когда нужно.