использование iterator() в django queryset


Я недавно столкнулся с некоторым странным поведением, и мне нужно проверить свое понимание.

Я использую простой фильтр в модели,а затем повторяю результаты.

Например

allbooks = Book.objects.filter(author = 'A.A. Milne')

for book in allbooks:
   do_something(book)
Как ни странно, он возвращал только частичный список книг.

Однако при использовании одного и того же кода и с использованием iterator () это, кажется, работает хорошо.

То есть

for book in allbooks.iterator():
    do_something(book)

Есть идеи, почему??

P. s. Я просмотрел документацию django, но не могу понять, как кевризет уже был бы закэширован в любом другом месте...

iterator() Вычисляет набор запросов (путем выполнения запроса) и возвращает итератор по результатам. Набор запросов обычно кэширует свои результаты внутри,так что повторные оценки не приводят к дополнительным запросам; iterator() вместо этого будет считывать результаты напрямую, не делая никакого кэширования на уровне набора запросов. Для набора запросов, который возвращает большое количество объектов, это часто приводит к повышению производительности и значительному снижению производительности. сокращение памяти

Обратите внимание, что использование iterator() В наборе запросов, который уже был вычислен, заставит его вычислять снова, повторяя запрос.

2 11

2 ответа:

Как ни странно, он возвращался только частично. список книг.

Это не то, как должен работать queryset. Перебора объект QuerySet должен дать вам все записи, возвращаемые базой данных. Отладки кода. Вы найдете ошибку, иначе отладите ее снова.

Это легко проверить в REPL. Выполнить manage.py shell:

from app.models import Model
for o in Model.objects.filter(fieldname="foo"): print o

#Let's see DB query
from django.db import connection
print connection.queries

Набор запросов обычно кэширует свои результаты внутри, так что повторные оценки не приводят к дополнительным запросам. В отличие от этого, iterator() будет считывать результаты напрямую, не делая никакого кэширования на уровне QuerySet.

Https://docs.djangoproject.com/en/dev/ref/models/querysets/