Решение Django N + 1

Я посетил http://guides.rubyonrails.org/active_record_querying.html после разговора с одноранговым узлом относительно N + 1 и серьезных последствий для плохих запросов БД.

ActiveRecord (Rails):

clients = Client.includes(:address).limit(10)

Если у клиента есть адреса, и я намереваюсь получить к ним доступ во время цикла через клиентов, Rails предоставляет includes, чтобы он знал, чтобы продолжить и добавить их в запрос, что устраняет 9 запросов сразу с места в пути.

Джанго:

https://github.com/lilspikey/django-batch-select обеспечивает поддержку пакетного запроса. Знаете ли вы о других библиотеках или трюках для достижения того, что Rails предоставляет выше, но в менее сложной усадьбе (как в примере с рельсами, где всего 19 символов фиксируют N + 1 и очень ясны)? Кроме того, пакетный выбор выдает проблему таким же образом или эти две разные вещи?

Кстати, я не спрашиваю о select_related, хотя это может показаться ответом на первый взгляд. Я говорю о ситуации, когда address имеет знаковый символ client.

Ответ 2

К сожалению, Django ORM пока еще не может этого сделать.

К счастью, это возможно сделать только в двух запросах, с небольшим количеством работы, выполненной в Python.

clients = list(Client.objects.all()[:10])
addresses = dict((x.client_id, x) for x in
    Address.objects.filter(client__in=clients))
for client in clients:
  print client, addresses[client.id]

Ответ 3

django-batch-select должен предоставить ответ на эту проблему, хотя я не пробовал ее. Ответ Игнасио выше кажется мне лучшим.