在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

您可以通过在django视图中添加延迟来确认是否是滞后问题,以便在任务成功完成几秒钟后等待。如果这解决了问题,您可能希望将handle_upload封装在事务中以进行阻止,直到数据库完全确认它已经完成,然后再返回。

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

例如,如果您要在一个全新的django请求/视图中的芹菜任务完成后调用后处理,那么您可能会看到DB中的新更改。然而,由于您的视图在任务执行时被阻止(这违背了celener-btw的目的),django在内部只保留输入视图时DB的快照。因此,您的get失败了,并且您在简单地输入django shell时直接确认了此行为。

你可以像你已经做的那样通过以下任何一种方式来解决这个问题:

  • 调用将刷新快照的事务管理
  • 更改DB端点缓存和自动提交策略
  • 在完成处理后,让芹菜回调django(web请求)(这很可能是你无论如何都想做的,因为阻塞django会破坏目的)

相关内容

  • 没有找到相关文章

最新更新