Итератор набора запросов Django () не работает должным образом - PullRequest
0 голосов
/ 27 декабря 2018

Я протестировал queryset.iterator() на основе документа Django.

Oracle и PostgreSQL используют серверные курсоры для потоковой передачи результатов из базы данных без загрузки всего набора результатов в память.

В случае серверных курсоров параметр chunk_size указывает число результатов, которые необходимо кэшировать на уровне драйвера базы данных.Извлечение больших кусков уменьшает количество циклических обходов между драйвером базы данных и базой данных за счет памяти.

В PostgreSQL серверные курсоры будут использоваться только в том случае, если для DISABLE_SERVER_SIDE_CURSORS задано значение False.

print(settings.DATABASES['default']['ENGINE']) # postgresql

class TestModel(Model):
    age = IntegerField(default=1)

# Insert 10 rows
for i in range(10):
    TestModel().save()

settings.DEBUG = True
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())   
# From now, every queries emitted by Django will be printed.    

print(settings.DISABLE_SERVER_SIDE_CURSORS) # False

for i in TestModel.objects.all().iterator(chunk_size=2):
    print(i.age)

(0.001) DECLARE "_django_curs_4369655232_3" NO SCROLL CURSOR WITH HOLD FOR SELECT "testmodel"."age" FROM "testmodel"; args=()

Я ожидал, что приведенный выше код попадет в базу данных 5 раз для каждых 2 строк из-за chunk_size=2 (а общее количество строк равно 10).

Однако, похоже,испустить только один запрос (над напечатанным запросом).

Я неправильно понимаю queryset.iterator()?

1 Ответ

0 голосов
/ 27 декабря 2018

Вы правильно поняли цель queryset.iterator().

В этом случае (PostgreSQL) Django объявил курсор (используя оператор DECLARE), который должен использоваться внутри итератора.

Чтобы извлечь данные из курсора, сначала нужно открыть курсор (используя оператор OPEN), а затем извлечь данные (используя оператор FETCH).

Похоже, что ваше ведение журнала не уловило ни одного из этих утверждений, происходящих внутри итератора, чтобы подтвердить это, вы можете установить ведение журнала на стороне PostgreSQL:).

...