Size: a a a

Django [ru] #STAY HOME

2020 June 17

AD

Alex Dem in Django [ru] #STAY HOME
Алексей Котенко
🖐

Есть ли возможность в prefetch_related сделать join on с несколькими условиями?

Кейс: есть модель A связанная двумя FK до модели B. Хочу из модели B получить все связанные записи A без N+1 запросов
а select_related пробовал?
источник

AD

Alex Dem in Django [ru] #STAY HOME
он делает обычный JOIN
источник

АК

Алексей Котенко... in Django [ru] #STAY HOME
class ModelA:
 field_1 = FK(B)
 field_2 = FK(B)

class ModelB:
  somefields = somevalues


Нужно получить ВСЕ связанные записи из A в 1 запрос
источник

АК

Алексей Котенко... in Django [ru] #STAY HOME
(про Raw конечно знаю, но это крайний вариант)
источник

МП

Михаил Павлов... in Django [ru] #STAY HOME
select_related для прямых fk
источник

МП

Михаил Павлов... in Django [ru] #STAY HOME
Prefetch для обратных связей
источник

АК

Алексей Котенко... in Django [ru] #STAY HOME
Alex Dem
а select_related пробовал?
здесь обратный запрос, он для прямых
источник

МП

Михаил Павлов... in Django [ru] #STAY HOME
Почему обратный?
источник

МП

Михаил Павлов... in Django [ru] #STAY HOME
filter().select_related()
источник

AG

Artem Gubatenko in Django [ru] #STAY HOME
Алексей Котенко
class ModelA:
 field_1 = FK(B)
 field_2 = FK(B)

class ModelB:
  somefields = somevalues


Нужно получить ВСЕ связанные записи из A в 1 запрос
так тут достаточно указать related_name и просто вписать в prefetch_related() нужное поле. Если не будешь дергать второе FK поле, то и доп.запровов не будет
источник

АК

Алексей Котенко... in Django [ru] #STAY HOME
Artem Gubatenko
так тут достаточно указать related_name и просто вписать в prefetch_related() нужное поле. Если не будешь дергать второе FK поле, то и доп.запровов не будет
конечно буду, мне же нужно получить все связанные записи, а не только по одной связи
источник

AG

Artem Gubatenko in Django [ru] #STAY HOME
Алексей Котенко
конечно буду, мне же нужно получить все связанные записи, а не только по одной связи
тогда используй Prefetch() как писал выше, только сделай в queryset=... запросе select_related
источник

МП

Михаил Павлов... in Django [ru] #STAY HOME
Так или иначе prefetch будет в два запроса
источник

МП

Михаил Павлов... in Django [ru] #STAY HOME
А select_related в один
источник

AD

Alex Dem in Django [ru] #STAY HOME
Алексей Котенко
конечно буду, мне же нужно получить все связанные записи, а не только по одной связи
у меня не получалось меньше двух запросов с prefetch_related
кто-то писал, что prefetch делает вложенный запрос, наверное, это правда
источник

AD

Alex Dem in Django [ru] #STAY HOME
Михаил Павлов
А select_related в один
++
я тоже так понимаю
источник

DT

Dan Tyan in Django [ru] #STAY HOME
Alex Dem
у меня не получалось меньше двух запросов с prefetch_related
кто-то писал, что prefetch делает вложенный запрос, наверное, это правда
префетч делает отдельный запрос
источник

Z

ZHU in Django [ru] #STAY HOME
Artem Gubatenko
наверно как-то так:
B.objects.prefetch_related(
   Prefetch(
       "<FK to A field>",
       queryset=A.objects.all()
   ),
)

ORM сама отберет связанные. А про join я не понял, но можно сделать там где queryset=....
не легче туда просто свой запрос join добавить ?
источник

AG

Artem Gubatenko in Django [ru] #STAY HOME
ZHU
не легче туда просто свой запрос join добавить ?
просто, изначально, он хотел делать запрос от B модели
источник

Z

ZHU in Django [ru] #STAY HOME
ZHU
не легче туда просто свой запрос join добавить ?
.extra( и добавить свой запрос который будет вытягивать что нужно)
источник