Подтвердить что ты не робот

Как отключить кеш запросов Django?

В моем приложении Django я неоднократно запускаю тот же запрос в моей базе данных (например, каждые 10 секунд). Затем я создаю сумму MD5 по запросу, который я получаю, и сравниваю с суммой MD5, созданной в предыдущем прогоне. Если оба они равны, данные не изменились, и веб-страница не нуждается в обновлении.

Пока я делаю это, данные в БД могут измениться.

Однако запрос возвращает тот же запрос, видимо, из-за кэширования запросов.

Как отключить кеш запросов и явно выполнить запрос в БД?

4b9b3361

Ответ 1

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

У меня возникла проблема, когда в другом процессе элементы добавлялись в базу данных, и я хотел отслеживать прогресс другого процесса, поэтому я открыл оболочку django и выдал следующее:

>>> MyData.objects.count()
74674

>>> MyData.objects.count()
74674

Значение не менялось, даже если оно действительно находилось в базе данных. Я понял, что, по крайней мере, с тем, как у меня были настройки MySQL и django, которые были у меня в транзакции, и я видел только "моментальный снимок" базы данных при открытии транзакции.

Так как с представлениями в django у меня было задано поведение autocommit, это было прекрасно для каждого представления, чтобы видеть только моментальный снимок, так как в следующий раз, когда было вызвано представление, оно было бы в другой транзакции. Но для части кода, которая не была автоматически совершена, она не увидела никаких изменений в db, кроме тех, которые были сделаны в этой транзакции.

Просто подумал, что я отвечу на этот ответ всем, кто может прийти в эту ситуацию.

Чтобы решить, совершите транзакцию, которая может быть выполнена вручную:

>> from django.db import transaction
>> transaction.enter_transaction_management()
>> transaction.commit() # Whenever you want to see new data

Ответ 2

Кэширование запросов применяется только в QuerySet. Другими словами, если вы дважды оцениваете один объект запроса, будет выполняться кеширование запросов. Но если вы делаете запрос каждые 10 секунд, предположительно это через cron, который каждый раз порождает новый процесс, так что Django не будет кэшировать что-либо.

Возможно, что ваш собственный кеш базы данных будет входить в работу, если вы повторно выполняете точно такой же запрос. Вы должны посмотреть на документацию для вашей СУБД, чтобы узнать, как правильно ее управлять.

Ответ 3

Ссылка, которую вы предоставляете в документации Django, подразумевает следующее:

>>> print [e.headline for e in Entry.objects.all()]
>>> print [e.pub_date for e in Entry.objects.all()]

создает две запросы к базе данных, а:

>>> queryset = Poll.objects.all()
>>> print [p.headline for p in queryset] # Evaluate the query set.
>>> print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.

использует кеш запросов, поскольку вы получаете доступ к тем же результатам оценки.

Ответ 4

Большое спасибо за ваши ответы, ваши ответы заставили меня сделать несколько шагов назад и переосмыслить.

Чтобы проверить кеширование на уровне СУБД, я ушел из Django и использовал оболочку script. Мне все-таки было удобно периодически запрашивать данные из SQLite db, а я добавлял данные во второй сеанс оболочки. Новые данные появились в периодических запросах сразу после того, как я их добавил, поэтому здесь нет кэширования запросов.

Это сузило его до части Django. Приведенный код не очень сложный, а небольшой вывод журнала и обзор кода выявили проблему: запрос, используемый для получения запроса, используемый, в свою очередь, для создания суммы MD5, имел ошибку и всегда был пустым. Поэтому сумма MD5 всегда была одинаковой. Действительно выглядел как кешированный результат - данные меняются, но набор запросов остается неизменным. Проблема не проявилась в приложении, поскольку для получения данных, отображаемых там, использовался другой запрос.

Извлеченный урок: если вы полностью озадачены, сделайте шаг назад и передумайте свои предположения.

Еще раз спасибо!: -)

Ответ 5

Я встретил эту проблему на версии 1.8 django. Существует нет прямого способа сделать это, но есть некоторые способы сделать повторную оценку и выполнение запроса, обратившись к db вместо кеша. Я нашел его в Документация Django Queryset

Я использовал один из них для решения моей проблемы. Это функция exists() запросов. len() и repr() также могут использоваться. Они тоже работали на меня.

Пример

queryset = ModelClass.objects.filter(....)
queryset.exists()

#or len(queryset)
#or repr(queryset)

#Now queryset is re-evaluated.