2009-12-11 106 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) – 2016-05-25 08:24:31

回答

41

我遇到了一些我認爲是某種緩存的行爲,但事實證明這是數據庫事務欺騙了我。

我曾在那裏在另一個進程中,項目被被添加到數據庫中的問題,我想監視其他工藝的進步,所以我打開了一個Django殼並發表如下:

>>> MyData.objects.count() 
74674 

>>> MyData.objects.count() 
74674 

該值沒有改變,即使它實際上在數據庫中。我意識到,至少在我使用MySQL & django的設置中,我處於事務中,並且在打開事務時只能看到數據庫的「快照」。

由於在django中的視圖中,我定義了自動提交行爲,因此每個視圖都只能看到一個快照,因爲下一次調用視圖時,它將處於不同的事務中。但是對於一段不是自動提交的代碼,除了那些在這個事務中做出的更改之外,它不會在db中看到任何更改。

只是覺得我會拋出這個答案在任何人誰可能會遇到這種情況。

解決的,提交您的事務,它可以像這樣做手工:

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

非常感謝,當運行一個偵聽隊列並且必須處理一些事件的命令時,我得到了這種確切的行爲,當發生這種情況時,處理器在命令開始運行後找不到用戶。 – victorcampos 2011-09-19 16:01:11

+1

transaction.commit_unless_managed()也爲我工作。 – 2013-10-30 18:17:41

+1

對於我以前發現很多次煩人的問題的完美答案!萬分感謝。 – Sarang 2014-11-05 06:04:34

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

查詢緩存僅適用於內的 QuerySet。換句話說,如果你兩次評估相同的查詢集對象,查詢緩存將會運行。但是如果你每隔10秒進行一次查詢,大概這是通過一個每次都會產生一個新進程的cron,所以Django沒有辦法緩存任何東西。

如果您反覆執行完全相同的查詢,您的數據庫自己的緩存可能會開始運行。您應該查看DBMS的文檔以瞭解如何正確管理該文檔。

+1

雖然正確,但這並不能回答清楚指向django queryset的問題。 @kekoa答案與OP的問題相匹配。 – sberder 2013-06-13 08:15:42

1

非常感謝您的回答,您的回覆使我回過頭幾步,重新思考。

爲了在DBMS級別上測試緩存,我離開了Django並使用了一個shell腳本,我無論如何都可以方便地定期從SQLite數據庫查詢數據,而我在第二個shell會話中添加了數據。新數據在我添加它們後立即顯示在週期性查詢中,因此在這裏沒有查詢緩存。

這縮小了它的Django部分。涉及的代碼不是很複雜,只有一點日誌輸出和代碼審查揭示了這個問題:用於獲取用於創建MD5總和的查詢集的查詢有一個錯誤,並且始終爲空。因此,MD5和總是相同的。確實看起來像一個緩存的結果 - 數據正在改變,但查詢集保持不變。 該問題沒有在應用程序中顯示,因爲使用了不同的查詢來獲取那裏顯示的數據。

獲得的經驗:如果你完全困惑,退後一步,重新考慮你的假設。

再次感謝! :-)

0

我會見了Django的1.8版本這個問題。有沒有直接的方法來做到這一點,但有一些方法可以通過訪問數據庫而不是緩存來重新評估和執行查詢集。我發現它在Django Queryset Documentation

我用其中之一來處理我的問題。它是查詢集的功能exists()。也可以使用len()repr()。他們也爲我工作。

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

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

#Now queryset is re-evaluated.