использование iterator () в наборе запросов django - PullRequest
12 голосов
/ 20 февраля 2011

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

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

например

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

for book in allbooks:
   do_something(book)

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

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

т.е.

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

Любая идея, почему ??

ps Я просмотрел документацию по django, но не вижу, как qeuryset будет кэшироваться уже где-либо еще ...

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

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

Ответы [ 2 ]

17 голосов
/ 21 февраля 2011

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

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

Это легко проверить в 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)
1 голос
/ 18 августа 2016

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

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

...