Django 模型没有保存到 Celery Task 中的数据库中

Posted

技术标签:

【中文标题】Django 模型没有保存到 Celery Task 中的数据库中【英文标题】:Django model doesn't get saved to database inside Celery Task 【发布时间】:2014-01-08 22:31:31 【问题描述】:

我遇到了一个非常糟糕的情况。我有以下设置。 我有一个 django 模型,它代表一个带有 django FSM field 的 FSM

我有一个 celery 任务,它发送一封电子邮件,然后推进主要对象 FSM 的状态。从 celery 任务的角度来看,对象“似乎”被保存了。但从主要 django 进程的角度来看,该对象没有被更新。奇怪的是辅助对象被正确保存到数据库中,然后可以从主 django 进程访问。

我在 Celery 任务的对象上显式调用 .save(),并且 date_last_modified = models.DateTimeField(auto_now=True, null=True) 字段在 Celery 任务中的时间戳比主线程晚,尽管我不确定这是否表明任何事情,即它可能已更新,但尚未将更新刷新到数据库。

我正在使用 django 1.5.1, PostgreSQL 9.3.0, 芹菜 v3.1.0, Redis 2.6.10

像这样运行 Celery $ celery -A tracking worker -E -B -l info

任何关于为什么会发生这种情况的想法将不胜感激

【问题讨论】:

【参考方案1】:

你是否在保存后重新获取对象? IE。不只是查看您在保存之前获得的实例吗?

【讨论】:

【参考方案2】:

我在 Django 1.5 上遇到过类似的问题

我猜是因为 Django 不会立即将更改提交到数据库。

添加

    'OPTIONS': 
        'autocommit': True
    

DATABASES 设置为我解决了这个问题。

在 Django 1.6+ 中不会存在问题,因为autocommit 是那里的默认值。

【讨论】:

【参考方案3】:

交易呢?您可以尝试设置CELERY_EAGER_PROPAGATES_EXCEPTIONS=True 并使用-l DEBUG 运行celery 以查看模型.save() 调用后是否发生任何错误。

还要注意并发更新。当一个进程读取模型时,celery 读取并保存相同的模型,如果初始进程稍后调用models.save(),它将覆盖其中的所有字段。

【讨论】:

并发更新对我来说是个问题,安装django-save-the-change.readthedocs.org 有帮助。谢谢! 现在 Django 有 .save(updated_fields=...) docs.djangoproject.com/en/3.0/ref/models/instances/… 可以用来代替 django-save-the-change 包

以上是关于Django 模型没有保存到 Celery Task 中的数据库中的主要内容,如果未能解决你的问题,请参考以下文章

Django,ImportError:无法导入名称 Celery,可能的循环导入?

如何将自定义模型添加到 django celery

对象未保存在 Celery 任务中

根据某些模型日期字段运行 Django Celery Beat 任务

python测试开发django-161.Celery 定时任务保存到数据库 (djcelery)

Django ElasticSearch Celery 任务模型调用返回“str”对象不可调用