Как кэшировать get_queryset() при использовании ForeignKeyWidget

Я импортирую данные с помощью django-import-export, но из-за использования ForeignKeyWidgets происходит много обращений к базе данных, что делает импорт очень медленным для всего нескольких 100 строк (проверено с помощью django-debug-toolbar).

На странице документации по Bulk imports говорится следующее:

"Если вы используете ForeignKeyWidget, это может повлиять на производительность, поскольку он считывает данные из базы данных для каждой строки. Если это проблема, создайте подкласс, который кэширует результаты get_queryset(), а не считывает их для каждого вызова."

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

Я попробовал следующее, но все равно вижу то же количество обращений к базе данных:

class CachedForeignKeyWidget(ForeignKeyWidget):
    def __init__(self, model, field="pk", use_natural_foreign_keys=False, **kwargs):
        self.cached_queryset = model.objects.all()

        super().__init__(model, field, use_natural_foreign_keys, **kwargs)

    def get_queryset(self, value, row, *args, **kwargs):
        return self.cached_queryset

Я проверил это, используя bulk_import скрипт.

Мое мнение заключается в том, что используется кэш QuerySet, и хотя вы видите вывод SELECT SQL для таблицы отношений, кэш используется, поэтому снижение производительности минимально.

В моих журналах видно, что поиск в таблице FK занимает незначительное время, даже при импорте 100 тыс. строк.

Я также вижу, что точка останова кэша сбивается во время импорта.

Если вы наблюдаете медленный импорт, значит, происходит что-то еще, поэтому было бы полезно понять, в чем проблема.

Пожалуйста, проведите собственное тестирование, но я считаю, что кэш Django QuerySet работает правильно и нет необходимости реализовывать собственное кэширование. Я обновлю документацию.

Вернуться на верх