2009-12-11 4 views
20

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

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

Однако запрос возвращает тот же запрос, по-видимому, из-за query caching.

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

+0

Возможный дубликат [Как заставить Django игнорировать все кэши и перезагружать данные?] (Http://stackoverflow.com/questions/3346124/how-do-i-force- django-to-ignore-any-caches-and-reload-data) –

ответ

41

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

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

>>> MyData.objects.count() 
74674 

>>> MyData.objects.count() 
74674 

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

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

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

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

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

Большое спасибо, я получил это точное поведение при запуске команды, которая слушает очередь и обрабатывает некоторые события. Когда это произошло, процессор не найдет пользователей, созданных после запуска команды – victorcampos

+1

«transaction.commit_unless_managed()' также работал для меня. –

+1

Идеальный ответ на проблему, которую я так часто раздражал в прошлом! Благодаря тонну. – Sarang

6

Ссылку вы предоставляете документации 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. 

использует кэш запросов, как вы обращаетесь к те же результаты оценки.

9

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

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

+1

Правильно, это не отвечает на вопрос, который четко указывает на набор запросов django. @kekoa ответ соответствует вопросу OP. – sberder

1

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

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

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

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

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

0

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

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

Пример

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

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

#Now queryset is re-evaluated. 
Смежные вопросы