在Celery任务中保存对象后,Django匹配查询不存在 [英] Django matching query does not exist after object save in Celery task

查看:263
本文介绍了在Celery任务中保存对象后,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和Celery 3.0

I use an ajax request to check for the uploaded file but after the celery task finishes i get a Photo matching query does not exist. The photo pk does exist and gets returned. If i query the database manually it works. Is this some sort of database lag? How can I fix it? I'm using Django 1.4 and Celery 3.0

推荐答案

您可以通过添加一个延迟到您的django视图,等待任务已经成功完成了几秒钟。如果这样解决了这个问题,你可能希望将事务中的handle_upload包装到一个事务中,直到数据库完全确认完毕才返回。

You can confirm if it is a lag issue by adding a delay to your django view to wait after the task has successfully finished for a a few seconds. If that resolves the problem you might want to wrap the handle_upload in a transaction to block until the db has completely confirmed it has finished before returning.

除了Django之外,DB也有自己的缓存。当django调用查询器时,它会从其自己的缓存中获取过时的数据(不太可能,除非您重复使用查询器,我在您发布的代码部分中看不到)或DB正在缓存相同Django连接的结果。

Beside Django, DB too has its own caches. When django invokes the queryset, it gets stale data either from its own caches (unlikely unless you were reusing querysets, which I didn't see in the portion of the code you posted) or the DB is caching results for the same Django connection.

例如,如果要在芹菜任务完成新的django请求/视图后调用后处理,您可能会看到DB中的新更改正常。但是,由于您的视图在执行任务时被阻止(这违反了芹菜btw的目的),所以django内部只保留在输入视图时的快照。因此,您的get失败,您只需简单地输入django shell即可直接确认此行为。

For example if you were to invoke post processing after the celery task has finished in a completely new django request/view you would probably see the new changes in DB just fine. However, since your view was blocked while the task was executing (which defeats the purpose of celery btw) internally django only keeps the snapshot of the DB at the time the view was entered. Therefore your get fails and you confirmed this behavior directly when simply entering the django shell.

您可以按照以下方式修复此问题:

You can fix this like you already did by either:


  • 调用将刷新快照的事务管理

  • 更改DB端点缓存和自动提交策略
  • $ b $一旦完成处理(这可能是你想要做的,因为阻止django失败的目的),b
  • 有芹菜回拨django(web请求)

  • invoking transactional management which will refresh the snapshot
  • changing on your DB endpoint caching and autocommit policies
  • have celery make a callback to django (web request) once it is done to finalize processing (which is likely what you want to do anyway because blocking django defeats the purpose)

这篇关于在Celery任务中保存对象后,Django匹配查询不存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆