在Celery任务中保存对象后,Django匹配查询不存在

时间:2012-07-18 10:19:03

标签: python mysql django celery django-celery

我有以下代码:

@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

1 个答案:

答案 0 :(得分:2)

您可以通过向django视图添加延迟来确认是否存在滞后问题,以便在任务成功完成几秒后等待。如果这解决了问题,您可能希望将事务中的handle_upload包装起来阻塞,直到db完全确认它已经完成并返回之前。

除了Django,DB也有自己的缓存。当django调用查询集时,它会从其自己的缓存中获取过时的数据(除非您重复使用查询集,否则我不会在您发布的代码部分中看到这些数据),或者DB正在缓存同一Django连接的结果。

例如,如果您在完全新的django请求/视图中完成芹菜任务后调用后处理,您可能会看到DB中的新更改就好了。但是,由于您的视图在执行任务时被阻止(这违背了celery btw的目的),因此内部django仅在输入视图时保留DB的快照。因此,当您只是输入django shell时,您的get会失败并直接确认此行为。

您可以通过以下方式解决此问题:

  • 调用将刷新快照的事务管理
  • 更改数据库端点缓存和自动提交策略
  • 让芹菜回复django(网页请求)一旦完成处理(这可能是你想要做的,因为阻止django会失败的目的)