Подключение и подзапросы
Для подключения одной таблицы к другой для загрузки связанной модели также можно использовать следующие способы.
-
select_related(related: Union[List, str]) -> QuerySet -
select_all(follow: bool = True) -> QuerySet -
prefetch_related(related: Union[List, str]) -> QuerySet -
Модель
- Метод mod.load ()
-
Агент наборов запросов
-
QuerysetProxy.select_related(related: Union[List, str])Методологии QuerysetProxy.select_all(follow: bool=True)МетодологияQuerysetProxy.prefetch_related(related: Union[List, str])Методологии
Выберите связанные
select_related(related: Union[List, str]) -> QuerySet
Позволяет предварительно извлекать связанные модели в ходе одного запроса.
При использовании select_lated всегда выполняется только один запрос к базе данных, что означает, что создается (иногда сложное) соединение, а последующие вложенные модели обрабатываются в Python.
Чтобы получить соответствующую модель, используйте имя внешнего ключа.
Для связывания зависимой модели используйте двойной подчеркивание между именами.
!!!Примечание Если вы из django, обратите внимание, что ormarselect_lated в django отличается от->, вы можете выбрать только один тип связи, тогда как в ormar вы можете выбрать связь между внешними ключами, обратной стороной внешнего ключа (следовательно, автоматически сгенерированным ключом) и полем ManyToMany (следовательно, все отношения в текущей версии).
!!!tip Для управления выбранными полями модели используйте методы fields() и except_fields ()QuerySet.
!!!tip Для управления порядком модели (главной или вложенной модели) используется метод order_by ().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Вы можете предоставить строку или список строк (или список полей/полей)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
Поле Many2Many ведет себя точно так же, как вы можете ввести имя поля Many2Many и получить окончательную модель для вас.
!!!предупреждает, что если вы задаете поле ForeignKey непустым (и поэтому необходимо) во время всех запросов, модели, которые не являются пустыми, будут предварительно отобраны автоматически, даже если вы не включили их в select_lated.
!!!Обратите внимание, что все методы, которые не возвращают строки, явно возвращают экземпляр QuerySet, чтобы можно было связать их друг с другом
1 2 3 | |
Выбрать все
select_all(follow: bool = False) -> QuerySet
По умолчанию при выборе all() никакие отношения не загружаются, а при выборе select_lated () необходимо указать все отношения, которые должны загружаться. Это может оказаться затруднительным, если вы хотите включить вложенные связи.
Именно поэтому был введен select_all (), поэтому все связи модели загружаются по умолчанию (в отличие от метода all()).
По умолчанию добавляются только те модели, которые непосредственно связаны с родительской моделью, из которой выполняется запрос.
Если задано значение "Слева"="Истина", она также добавляет связанную модель для связанной модели.
!!!info Чтобы не попасть в бесконечный цикл, связанная модель также сохраняет связь с родительской моделью, которая получает доступ к набору моделей.
1 2 3 4 | |
Ниже приводятся даты выборки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
Чтобы выбрать все компании со всеми филиалами и адресами, вам нужно просто запросить:
1 2 3 4 | |
Конечно, в этом случае очень легко задать явно выраженное имя связи в select_lated, но если у вас несколько отношений, то преимущества select_all () будут очевидны.
Например, если компания имеет 3 отношения, и все 3 отношения имеют свои собственные 3 отношения, необходимо отправить 9 строк в адрес select_lated, а select_all () изменить имя связи невозможно.
!!!note Обратите внимание, что select_all () можно связать с другими методами QuerySet, такими как filter, exclude_fields и т. д. Чтобы исключить связи, используйте вызов except_fields () с именами связей, которые необходимо исключить (также вложенными).
Предварительный отбор связан
prefetch_related(related: Union[List, str]) -> QuerySet
Позволяет предварительно извлекать связанные модели во время запроса, но в отличие от select_lated каждая последующая модель извлекается в отдельном запросе базы данных.
При использовании prefetch_lated каждая модель выполняет по одному запросу для базы данных, что означает, что вы выполняете несколько запросов один за другим.
Чтобы получить соответствующую модель, используйте имя внешнего ключа.
Для связывания зависимой модели используйте двойной подчеркивание между именами.
!!!tip Для управления выбранными полями модели используйте методы fields() и except_fields ()QuerySet.
!!!tip Для управления порядком модели (главной или вложенной модели) используется метод order_by ().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
Вы можете предоставить список строк или строк
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
Поле Many2Many ведет себя точно так же, как вы можете ввести имя поля Many2Many и получить окончательную модель для вас.
!!!предупреждает, что если вы задаете поле ForeignKey непустым (и поэтому необходимо) во время всех запросов, модели, которые не являются пустыми, будут автоматически отобраны, даже если вы не включили их в select_lated.
!!!Обратите внимание, что все методы, которые не возвращают строки, явно возвращают экземпляр QuerySet, чтобы можно было связать их друг с другом
1 2 3 | |
Выбор корреляций и предварительной обработки
Какой из-> select_lated или prefetch_lated вы должны использовать?
Ну, это на самом деле зависит от ваших данных. Лучший ответ-попробовать сами, чтобы увидеть, какой из них работает быстрее/лучше в пределах вашей системы.
Что нужно помнить:
Выявление
Количество запросов: select_lated всегда выполняет один запрос в базе данных, тогда как prefetch_lated выполняет несколько запросов. Обычно запрос (ввода-вывод) является самым медленным, но не обязательно.
Количество строк: предположим, что таблица A содержит 10 000 объектов, каждый из которых имеет 3 подобъекта в таблице B, а затем каждый объект в таблице B имеет 2 подобъекта в таблице C. Как показано ниже:
1 2 3 4 5 6 7 8 9 10 11 | |
Это означает, что select_lated всегда возвращает 60 000 строк (10 000 *3 *2), затем сжимает до 10 000 моделей.
Сколько строк будет возвращено prefetch_lated?
Ну, это зависит от того, что если каждая модель B и C является уникальной, то она возвращает 10 000 строк в первом запросе и 30 000 строк во втором.(Каждый из 3 дочерних элементов A в таблице B является уникальным) и 60 000 строк (каждый дочерний элемент в таблице B является уникальным). 2 подуровня модели B в таблице C являются уникальными для третьего запроса.
В этом случае select_lated представляется более предпочтительным вариантом, поскольку он не только запускает один запрос по сравнению с 3 prefetch_lated, но и возвращает 60 000 строк по сравнению со 100 000 prefetch_lated (10+30+60k).
Но что делать, если каждая модель A имеет 3 идентичные модели B, и каждая модель C имеет идентичную модель C? select_lated возвращает 60 000 строк, а prefetch_lated возвращает 10 000 строк модели A, 3 строки модели B и 2 строки модели C. Таким образом, общее количество строк составляет 10 006. Теперь, в зависимости от структуры модели (т. е. если она имеет длинные поля Text() и т. д.), prefetch_lated может работать быстрее, хотя для этого требуется выполнить три отдельных запроса вместо одного.
Память
ormar не ведет реестр загруженных моделей.
Это означает, что в приведенном выше примере select_lated всегда будет 10 000 моделей A и 30 000 моделей B (даже если в базе данных имеется только число строк 3-select_lated, будет создана новая дочерняя модель для каждой родительской модели). и 60 000 моделей C.
Если строки 1, 10, 100 и т. д. используют одну и ту же модель B и обновляют одну из них, остальные строки, в которых используется один и тот же дочерний объект, не обновляются немедленно. Если изменения сохраняются в базе данных, изменения будут доступны только после перезагрузки (загрузите каждый дочерний объект отдельно или перезагрузите весь запрос). Это означает, что select_lated будет использоваться больше памяти, так как каждый подобъект будет преобразован как новый объект
- Очевидно, что они используют свое пространство.
!!!Обратите внимание, что, если мы решим внедрить кэш, это может измениться в будущих версиях.
!!! Предупреждение, что по умолчанию все дочерние объекты (или события, в которых одна и та же модель загружается более двух раз) являются полностью независимыми, разными объектами Python, хотя они представляют одну и ту же строку в базе данных.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
Вместо этого, используя prefetch_lated, каждая отдельная дочерняя модель создается только один раз, а одна и та же дочерняя модель делится между всеми родительскими моделями. Это означает, что в приведенном выше примере prefetch_lated, если в таблице B есть 3 различные модели, а в таблице C-2 разные модели, то все экземпляры модели A будут иметь общий доступ только к 5 субвложенным моделям. Это также означает, что при обновлении какого-либо свойства все родительские объекты обновляют его, так как они имеют одни и те же дочерние объекты.
Метод модели
Каждый экземпляр модели имеет набор способов сохранения, обновления или загрузки самого себя.
Загрузить
Вы можете загрузить связанную модель ForeignKey, вызвав метод load().
load() можно использовать для обновления модели из базы данных, если она была изменена другим процессом.
!!!tip Узнайте больше о методе load() в методах модели
Метод QuerysetProxy
При прямом доступе к соответствующему полю ManyToMany и ReverseForeignKey, возвращайтесь к списку связанных моделей.
Но в то же время он предоставляет подмножество API QuerySet, поэтому вы можете фильтровать, создавать и выбирать связанные модели непосредственно из родительской модели.
Выберите связанные
То же самое, что и функция select_lated выше, но позволяет получать связанные объекты с другого конца отношения.
Tip
Выбрать все
То же самое, что и функция select_all выше, но позволяет получать связанные объекты с другого конца отношения.
Tip
Предварительный отбор связан
То же самое, что и функция prefetch_lated выше, но позволяет получать связанные объекты с другого конца отношения.
Tip