2010-11-20 9 views
2

次のコード行は、私がデータをクランチするために使用する分散型ワーカーモデルを示しています。ジョブはデータベースに作成され、そのデータは大きなドライブに送られ、すべての情報が利用可能になると、ジョブステータスは「待機中」に設定されます。ここから、複数のアクティブなワーカーが出てくる。時には、それぞれが仕事を「主張」しようとするクエリを発行する。要求を同期させるために、クエリが候補を返す場合、ジョブの状態を直ちに変更するトランザクションにクエリがカプセル化されます。ここまでは順調ですね。@staticmethodでのdjango QuerySetキャッシングの回避

問題は、申し立ての呼び出しが初めて機能することです。 QuerySetとそのキャッシングの動作を読み上げると、静的メソッドとQuerySetキャッシングを組み合わせると常にキャッシュに戻ってしまうようです...自分自身を参照してください:

私はdjango.db.models.Modelから派生したクラスを持っています:

class Job(models.Model): 
[...] 

ここで、以下の静的関数を定義します。

@staticmethod 
@transaction.commit_on_success 
def claim(): 
    # select the oldest, top priority job and 
    # update its record 
    jobs = Job.objects.filter(state__exact = 'WAITING').order_by('-priority', 'create_timestamp') 
    if jobs.count() > 0: 
     j = jobs[0] 
     j.state = 'CLAIMED' 
     j.save() 
     logger.info('Job::claim: claimed %s' % j.name) 
     return j 
    return None 

私が間違っていることは明らかですか?これを扱う良い方法は何でしょうか? QuerySetが静的メソッドのさまざまな呼び出しで結果をキャッシュしないようにするにはどうすればよいですか?それとも、私は何かを逃して、ファントムを追いかけていますか?どんな助けでも大歓迎です...ありがとう!

答えて

0

クエリーを実行する単純なモジュールレベルの関数claim_jobs()だけではないのはなぜですか?

def claim_jobs(): 

    jobs = Job.objects.filter(...) 
    ... etc. 
+0

Mmh。デザインが悪い - 静的メソッドは実際にクラスに属します。 – Marc

+0

は、あなたがどのように見ているかによって異なります。プレーン関数がより効率的である可能性は非常に高いです。 – Evgeny

3

ソリューションは非常に、非常に些細なことが判明:速度は、ここで、このような超重要な問題ではないとして、クエリはトリックを行う前に、

Jobs.objects.update() 

を呼び出します。また、いくつかの選択肢について詳述しているthis postへの称賛。

+0

いいえ、私はあなたがこの目的のためにアップデートを使うことができるかどうか分かりませんでした。 djangoはupdate()呼び出しでデータベースにヒットしますか? – Evgeny

+0

実際には、カスタムモデルマネージャを作成してから、Jobs.objects.claim_one()を使用することもできます。 – Evgeny

関連する問題