2012-07-18 82 views
2

我有以下代碼:Django的匹配查詢不芹菜任務對象後存在保存

@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請求檢查上傳的文件,但芹菜任務完成,我收到了照片匹配後查詢不存在。照片PK確實存在並被返回。如果我手動查詢數據庫它工作。這是某種數據庫滯後嗎?我該如何解決它? 我正在使用Django 1.4和芹菜3.0

+0

你的transac重刑設置看起來像? – Shaung 2012-07-18 10:34:55

+0

我在默認情況下保留了大部分設置。我已經改變了唯一的事情就是CELERY_RESULT_BACKEND =「AMQP」 CELERY_TASK_RESULT_EXPIRES = 3600 ,因爲它會掛起即使在完成後等待的任務。 – andrei 2012-07-18 11:19:34

回答

2

您可以通過向django視圖添加延遲,以確認它是否是滯後問題,以便在任務成功完成幾秒鐘後等待。如果解決了這個問題,您可能想要將事務中的handle_upload封裝到事務中,直到數據庫在返回之前完全確認它已完成。

除了Django,DB也有它自己的緩存。當django調用查詢集時,它會從它自己的緩存中獲取陳舊的數據(除非您重複使用查詢集,這在我發佈的代碼部分中沒有看到),或者數據庫正在爲相同的Django連接緩存結果。

例如,如果你要調用後處理的芹菜任務在一個完全新的Django的請求結束後/查看您可能會看到在DB的新變化就好了。但是,由於您的視圖在任務執行時被阻塞(這違背了芹菜btw的目的),因此內部django僅在視圖輸入時保留數據庫的快照。因此,你的失敗,你直接確認這種行爲時,只需進入Django殼。

可以解決這個問題就像你已經做了有兩種方法:

  • 調用事務管理,這將刷新快照
  • 在您的數據庫端點高速緩存和自動提交政策改變
  • 已經芹菜做出回調django(網絡請求)一旦完成處理(這可能是你想要做的任何事情,因爲阻止Django擊敗目的)
+0

我在視圖中查詢數據庫之前已經添加了5秒的延遲,但我得到相同的錯誤。我現在不知道發生了什麼。我應該提及它在Celery 2.5和Django 1.3上的工作。 – andrei 2012-07-18 13:02:43

+0

我已經與任務並行啓動了一個django python shell,無論我等待多少,它都不會獲得對象。在關閉殼體並打開一個新殼體之後,我沒有任何問題地檢索到了該物體。該對象在任務完成後顯示在django管理員權限中。數據庫緩存了什麼? – andrei 2012-07-18 13:26:41

+0

是的,在視圖函數中,Django具有數據庫狀態的快照,即使數據庫已更改,在本地事務完成之前也不會看到它。有關更多信息,請參閱http://stackoverflow.com/questions/1886909/how-to-disable-django-query-cache上的評論。 – astevanovic 2012-07-18 15:22:10