Как я могу предварительно выбрать в peewee? - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь сделать оптимизированный SQL-запрос, чтобы получить список объектов A, у которого есть список объектов B, у которого есть список объектов C и D и отношение многих ко многим с E

Я пытался решить проблему с агрегатными строками, но у меня возникают проблемы, когда нет объектов типа B или C или D.

Например, я пробовал этот запрос:

aa = A.alias()
query = (A.select(A, B, aa, C, D, E).join(B, peewee.JOIN_LEFT_OUTER).join(aa, peewee.JOIN_LEFT_OUTER).switch(B).join(C, peewee.JOIN_LEFT_OUTER).switch(B).join(D, peewee.JOIN.LEFT_OUTER).switch(B).join(E, peewee.JOIN_LEFT_OUTER))

Затем я дедуплицирую данные с aggregate_rows. Это работает, когда есть строки B и C и D, но когда их нет, я не получаю соответствующий объект A с пустым списком B или C или D.

Я также пытался использовать предварительную выборкуно когда я получаю доступ, AB peewee не запускает запрос (Хорошо), но, когда я получаю доступ к ABC, peewee запускает запрос (Плохо).

A_objects = peewee.prefetch(A,B,C,D,E)

Я потерян, я не знаючто я делаю не так.

Ответы [ 2 ]

0 голосов
/ 30 октября 2019

Наконец-то я нашел решение. Как сказал мне Колейфер, и, как я читал в документации, вместо агрегирования_row можно использовать метод prefetch. В версии, над которой я работал, перед тем, как задавать вопросы, было 2.x. Эта версия выбирает данные предварительной выборки с суффиксом _prefetch. Например, если A имеет атрибут A.something, при его предварительном извлечении он будет восстановлен в A.something_prefetch. Зефир работает, разговаривая напрямую с нашей моделью. Это означает, что когда он хочет получить что-то A., он будет запрашивать что-то, а не A.something_prefetch. A.something в peewee 2.x является объектом SelectQuery, поэтому он будет выполнять SQL-запрос вместо восстановления предварительно выбранных данных.

Наконец, я обновил версию peewee до 3.x, и теперь она работает. Я не знаю, может ли Колейфер сказать нам, верен ли этот ответ или нет, но сейчас он работает.

Надеюсь, это поможет!

0 голосов
/ 29 октября 2019

Святое дерьмо, это много отношений. Вы профилировали свой код и уверены, что предварительная выборка значительно улучшит время загрузки? Является ли самый внешний цикл (A) в вашем примере очень большим списком? Я бы посоветовал разобраться в этом, прежде чем пытаться «оптимизировать» ваш запрос.

aggregate_rows ()

Похоже, вы на Peewee 2.x? Это довольно старый и выход из обслуживания. Этот метод был удален в 3.x, потому что он очень неэффективен в 99% случаев.

и отношение многих ко многим с E

Вероятно, это проблема,«Многие ко многим» на самом деле представляют собой 2 таблицы - соединительную таблицу с двумя внешними ключами, одну для источника и одну для целевых объектов, связанных в «многие ко многим». Поэтому, если вы хотите попытаться выполнить предварительную выборку из множества ко многим, вам нужно будет включить соединительную таблицу. Вероятно, это будет довольно сложно.

Вы можете увидеть несколько примеров того, как выполнить предварительную выборку из множества ко многим в тестах:

https://github.com/coleifer/peewee/blob/7bfe65cd3689e7bbd0ad5345c0454cba1b559b94/tests/manytomany.py#L278-L308

...