2009-12-11 33 views
20

私のDjangoアプリケーションでは、データベース上で同じクエリを繰り返し実行します(10秒ごとなど)。 それから、私が受け取ったクエリーセット上にMD5の合計を作成し、前の実行で作成したMD5の合計と比較します。両方が等しい場合、データは変更されず、Webページは更新する必要はありません。Djangoクエリキャッシュを無効にするにはどうすればよいですか?

これを実行している間、DBのデータが変更されることがあります。

しかし、クエリは同じクエリセットを返します。明らかにquery cachingが原因です。

クエリキャッシュを無効にして、DBで明示的にクエリを実行するにはどうすればよいですか?

+0

[どのように私はすべてのキャッシュを無視してデータを再ロードするためにはDjangoを強制しますか?]の可能な重複(http://stackoverflow.com/questions/3346124/how-do-i-force- django-to-ignore-any-caches-and-reload-data) –

答えて

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

+1

'transaction.commit_unless_managedまた私のために働いた。 –

+1

私は過去に何度も迷惑をかける問題の完璧な答え!ありがとう、トン。 – Sarang

6

あなたはDjangoのドキュメントへの提供のリンクは、次のことを意味:あなたがアクセスしているよう

>>> 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. 

は、クエリキャッシュを使用しています。一方で

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

は、データベースへの2つのクエリを作成します同じ評価結果。

9

クエリキャッシュは、内にのみ適用されます。クエリセットはです。つまり、同じクエリーセットオブジェクトを2回評価すると、クエリーキャッシングが動作します。しかし、10秒ごとにクエリを実行している場合は、おそらく毎回新しいプロセスを生成するcron経由であるため、Djangoが何かをキャッシュする方法はありません。

正確に同じクエリを繰り返し実行している場合、データベースのキャッシュが動作する可能性があります。 DBMSのドキュメントを見て、適切に管理する方法を見てください。

+1

これは間違いなく、これはdjango querysetで明確に指摘している質問には答えていません。 @kekoa答えはOPの質問と一致しています。 – sberder

1

ご回答ありがとうございました。返信いただきありがとうございました。私はいくつかのステップを取り戻し、再考しました。

DBMSレベルでキャッシュをテストするために、私はDjangoから離れ、SQLite dbのデータを定期的に照会するシェルスクリプトを使用しましたが、2番目のシェルセッションでデータを追加しました。新しいデータは、追加した直後の定期クエリーに表示されたので、ここではクエリーはキャッシュされません。

これは、Djangoの部分に絞りました。関係するコードはあまり複雑ではなく、少しのログ出力とコードレビューによって問題が明らかになりました。MD5合計を作成するために使用されるクエリセットを取得するために使用されたクエリにはエラーがあり、常に空でした。したがって、MD5合計は常に同じでした。実際にキャッシュされた結果のように見えました - データは変化していますが、クエリーセットは同じままです。 そこに表示されているデータを取得するために別のクエリが使用されたため、問題がアプリケーションに表示されませんでした。

教訓:あなたが完全に困惑しているなら、一歩前倒しして前提を再考してください。

もう一度おねがいします! :-)

0

私は、Djangoのバージョン1.8でこの問題に会いました。それを直接行う方法はありませんが、キャッシュの代わりにdbにアクセスすることによってクエリーセットを再評価して実行するいくつかの方法があります。私はそれを見つけたDjango Queryset Documentation

私は自分の問題を処理するためにそれらの1つを使用しました。クエリーセットの機能はexists()です。 len()およびrepr()も使用することができる。彼らも私のために働いた。

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

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

#Now queryset is re-evaluated. 
関連する問題