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

标签 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 请求来检查上传的文件,但在 celery 任务完成后,我得到一个照片匹配查询不存在。照片 pk 确实存在并被返回。如果我手动查询数据库,它可以工作。这是某种数据库滞后吗?我该如何解决? 我正在使用 Django 1.4 和 Celery 3.0

最佳答案

您可以通过在 django View 中添加延迟以在任务成功完成几秒钟后等待来确认这是否是延迟问题。如果这样可以解决问题,您可能希望将 handle_upload 包装在事务中以阻塞,直到 db 完全确认它已完成,然后再返回。

除了 Django,DB 也有自己的缓存。当 django 调用查询集时,它会从自己的缓存中获取陈旧数据(除非您正在重用查询集,我在您发布的代码部分中没有看到)或者数据库正在缓存相同 Django 连接的结果。

例如,如果您要在 celery 任务完成后在一个全新的 django 请求/ View 中调用后处理,您可能会在 DB 中看到新的变化。但是,由于您的 View 在任务执行时被阻止(这违背了 celery 顺便说一句的目的),因此 django 仅在进入 View 时保留数据库的快照。因此,您的获取失败,并且您在简单地进入 django shell 时直接确认了此行为。

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

  • 调用将刷新快照的事务管理
  • 更改您的数据库端点缓存和自动提交策略
  • 在完成处理后让 celery 对 django(网络请求)进行回调(这很可能是您无论如何都想做的,因为阻止 django 会破坏目的)

关于python - 在 Celery 任务中保存对象后,Django 匹配查询不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11539152/

相关文章:

python - 使用python从图像中提取线条

mysql - 仅当日期时间为空时才更新 mysqli

python - Django RESTful API 错误 "type object ' User' has no attribute '_meta' "

python - Pyinstaller 和 PyQt5 错误 "Cannot find existing PyQt5 plugin directories"

python - 如何在 tkinter 中单击按钮后更新 Canvas 上的文本

c# - 单个 ODBC ExecuteNonQuery 中的多个插入语句 (C#)

mysql - 在数据库中,如何存储可以有多种语言的文本?

python - 如何使用 django-filters 重命名(在 API 中公开)过滤器字段名称?

python - django.request 记录器没有传播到根?

python - 点云数据的快速搜索算法