Django芹菜任务:新创建的模型DoesNotExist

时间:2013-04-03 14:37:31

标签: django asynchronous celery django-celery

为什么我已经创建了一个模型实例,当从之后直接启动的芹菜任务中查询时,找不到?例如:

# app.views

model = Model.objects.create()    # I create my lovely model in a view
from app.tasks import ModelTask   # I import my Async celery task
ModelTask.delay(model.pk)         # I start the task

一切看起来都很好,当然,如果我在create()调用后的任何时候查询,模型应该存在于数据库中。

更新1 :我使用Django为我的观点提供的默认transaction.autocommit行为。

但是下面的任务会引发ObjectDoesNotExist例外:

# app.tasks

class ModelTask(Task):
    def run(self, model_pk):
        from app.models import Model
        Model.objects.get(pk=model_pk)

在我的测试中,正如预期的那样,model_pk是一个正确的正整数ID。

结论

我假设有一些异步/"单独的过程"这里出现的问题,但我不知道它是什么。如果觉得我有一些明显的错误。

我不认为数据库事务是答案,因为Django默认" autocommit"方法确保在调用create()方法后立即执行数据库操作。

3 个答案:

答案 0 :(得分:7)

我的代码中遇到了同样的问题。经过长时间的调查,我发现种族情况正在发生,因为我正在使用@transaction.commit_on_success装饰。因此,只有在返回视图后才会提交事务。在我打电话给芹菜任务之后发生了这件事。

一旦我删除了“commit_on_success”装饰器,一切都开始按预期工作了。因为Django的default transaction behavior是在任何数据库更改操作之后提交事务。

您可能还想确保您没有使用TransactionMiddleware,因为它与@transaction.commit_on_success装饰器类似。如果您想继续使用它,您应该考虑在视图中使用@transaction.autocommit decorator与芹菜任务,或@transaction.commit_manually

答案 1 :(得分:1)

这些答案需要更新。 Django现在有transaction.on_commit()专门针对此确切问题而构建,他们甚至提供了一个带有任务的示例:

transaction.on_commit(lambda: some_celery_task.delay('arg1'))

https://docs.djangoproject.com/en/2.1/topics/db/transactions/#django.db.transaction.on_commit

答案 2 :(得分:-1)

由于我的数据库的ATOMIC_REQUEST标志,我遇到了类似的问题。更改配置后:

DATABASES['default']['ATOMIC_REQUESTS'] = False

问题消失

相关问题