Итератор набора запросов Django() не работает должным образом

Я протестировал 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()?


person SangminKim    schedule 27.12.2018    source источник


Ответы (1)


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

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

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

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

person iklinac    schedule 27.12.2018