Сталкивались ли с недостатками ORM SQLAlchemy?
Что проверяют
Работали ли вы с ORM на объёмах или читали документацию. Ответ «недостатков нет» закрывает вопрос сразу: ждут конкретные грабли и понимание, что ORM это отображение объектов на строки, а не замена SQL.
Как отвечать
Назовите то, на чём обжигаются:
- N+1: обращение к
relationshipв цикле порождает запрос на каждую строку. Лечится черезselectinloadилиjoinedload, но и лечение не бесплатное; DetachedInstanceError: объект пережил сессию, и ленивая связь падает при первом обращении. В асинхронном коде правила жёстче, ленивая загрузка там запрещена и связи грузятся явно;- неявный
autoflush: перед очередным запросом сессия сбрасывает изменения, и нарушение ограничения прилетает в неожиданном месте; - массовая запись: ORM работает поштучно, для больших пачек нужен слой Core с
insert()или bulk-операции; - тяжёлая аналитика: оконные функции и многоэтажные
CTEна ORM читаются хуже чистого SQL.
Сильный финал: SQLAlchemy честно двухслойная, Core существует ровно для случаев, где ORM мешает, и уход в сырой SQL ради отчёта это нормальный инструмент. Добавьте, что смотрите сгенерированный запрос через echo и план через EXPLAIN.
Где спотыкаются
Ругают ORM за медленность, ни разу не посмотрев, какой SQL она сгенерировала. Почти всегда виноват не слой абстракции, а запрос в цикле или выборка всех колонок там, где нужны две.
Лечат N+1 через joinedload для всего подряд. По нескольким коллекциям это даёт декартово произведение, строки размножаются, и без unique() в результате появляются дубликаты объектов.
Держат одну сессию на всё приложение. Она хранит identity map и открытую транзакцию: объекты протухают, блокировки висят, а в многопоточном коде сессия ещё и не рассчитана на общий доступ.