Выбор ответа Senior SQLAlchemy 2.0 обновлено

joinedload коллекции и unique()

Вопрос

Почему при select(User).options(joinedload(User.orders)) SQLAlchemy 2.0 требует вызвать .unique() у результата?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: JOIN по коллекции дублирует пользователей по числу заказов, unique() их схлопывает. Пользователь с пятью заказами приходит пятью строками.

Варианты ответа

  1. JOIN по коллекции дублирует пользователей по числу заказов, unique() их схлопываетправильный ответ
  2. unique() добавляет уникальный индекс на users.id, без которого JOIN медленный
  3. unique() нужен только для SQLite, где JOIN возвращает дубликаты строк
  4. Это требование для любого запроса в 2.0, независимо от стратегии загрузки

Разбор

Пользователь с пятью заказами приходит пятью строками. ORM склеивает заказы в коллекцию, но сами строки результата дублируют пользователя, и 2.0 явно просит .unique() при eager-загрузке коллекций через JOIN. К индексам и диалектам это не относится. Ещё один довод за selectinload для коллекций.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме