6

次のコードがあります。

@task()
def handle_upload(title, temp_file, user_id):
    .
    .
    .
    photo.save()
    #if i insert here "photo2 = Photo.objects.get(pk=photo.pk)" it works, including the         view function
    return photo.pk

#view function
def upload_status(request):
    task_id = request.POST['task_id']

    async_result = AsyncResult(task_id)
    photo_id = async_result.get()
    if async_result.successful(): 
        photo = Photo.objects.get(pk=photo_id)

アップロードされたファイルを確認するために ajax リクエストを使用しますが、セロリ タスクが終了した後、Photo matching query does not exist が表示されます。写真 pk は存在し、返されます。データベースに手動でクエリを実行すると、機能します。これはある種のデータベースラグですか? どうすれば修正できますか?Django 1.4 と Celery 3.0 を使用しています

4

1 に答える 1

2

タスクが正常に終了した後、数秒間待機する遅延を django ビューに追加することで、ラグの問題であるかどうかを確認できます。これで問題が解決する場合は、handle_upload をトランザクションにラップして、db が完全に終了したことを確認してから戻るまでブロックすることをお勧めします。

Django のほかに、DB にも独自のキャッシュがあります。django がクエリセットを呼び出すと、独自のキャッシュから古いデータを取得するか (投稿したコードの一部では見られなかったクエリセットを再利用していない限り、可能性は低い)、DB が同じ Django 接続の結果をキャッシュしています。

たとえば、セロリ タスクが完全に新しい django リクエスト/ビューで終了した後に後処理を呼び出すと、DB の新しい変更が問題なく表示される可能性があります。ただし、タスクの実行中にビューがブロックされたため (これはセロリの目的を無効にします)、内部的に django はビューが入力された時点の DB のスナップショットのみを保持します。したがって、 get が失敗し、単に django シェルに入ったときにこの動作を直接確認しました。

これは、次のいずれかで既に行ったように修正できます。

  • スナップショットを更新するトランザクション管理を呼び出す
  • DB エンドポイントのキャッシュと自動コミット ポリシーの変更
  • 処理を終了するためにセロリにdjangoへのコールバック(Webリクエスト)を作成させます(djangoをブロックすると目的が無効になるため、これはおそらくあなたがやりたいことです)
于 2012-07-18T12:19:53.230 に答える