Для чего используется ORM
Что проверяют
Понимаете ли вы, какую задачу решает ORM и чем за это платит. Ответ «чтобы не писать SQL» считается слабым.
Как отвечать
ORM отображает строки таблиц на объекты языка и берёт на себя рутину: генерацию запросов, отслеживание изменений, связи между сущностями, миграции схемы, пул соединений, экранирование параметров.
Что это даёт:
- меньше однотипного кода: CRUD, выборка по ключу, сохранение связей;
- единая модель: схема описана в одном месте и синхронизируется миграциями;
- безопасность по построению: параметры подставляются, а не склеиваются, что снимает инъекции;
- переносимость между СУБД, хотя на практике она частичная;
- типизация и автодополнение в коде вместо строк с SQL.
Чем платит, и это обязательная часть ответа: скрытая генерация запросов, из-за которой легко получить неоптимальный план; проблема N+1, когда обращение к связи в цикле превращается в тысячу запросов; накладные расходы на отображение объектов при больших выборках; ленивая загрузка вне сессии.
Отсюда практика: ORM на девяносто процентов кода, тяжёлые аналитические запросы руками. Все взрослые библиотеки это позволяют: в SQLAlchemy есть Core и text(), в Django raw и annotate.
Ключевая мысль: ORM не отменяет знания SQL. Отлаживать всё равно приходится сгенерированный запрос и его план.
Где спотыкаются
Отвечают «чтобы не писать SQL» и не могут назвать ни одного минуса.
Не знают про N+1 или не могут назвать лечение (selectinload, join, prefetch_related).
Не умеют посмотреть, какой запрос сгенерировался.
Считают переносимость между базами реальной, хотя специфичные возможности всё равно ломают её.