芹菜任务中的数据库已过期

时间:2020-02-19 10:47:08

标签: python django celery django-celery

我有Django == 2.2.8和celery == 4.3.0,作为经纪人是redis。

具有非常简单的drf视图来创建BankEntry

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        instance = serializer.save()
        bank_entry = BankEntries.objects.get(pk=instance.id)
        async_task = async_create_transactions.delay(bank_entry.pk) <--- celery task
@celery_app.task()
def async_create_transactions(entry_id):
    bank_entry = BankEntries.objects.filter(pk=entry_id).first()
    if bank_entry: <---- HERE SOMETIMES BANK_ENTRY IS NONE, But why, we just created it
        return bank_entry.create_entries()

不知道为什么,但是在async_create_transactions中,我可以创建BankEntry。 我确定celery设置使用相同的数据库,因为在下一个async_create_transactions调用中,我可以看到以前的BankEntry,而不能看到当前的。

我没有钩子,信号,postgresql函数和其他副作用。

1 个答案:

答案 0 :(得分:0)

最有可能发生的情况是,您的后台任务正在尝试在serializer.save()完全完成之前访问数据库条目。我以前也遇到过类似的问题。

您可以做的是在调用async_create_transactions之后增加一小段延迟,这将为完成记录保存留出时间。因此,您可以执行以下操作:

from time import sleep

@celery_app.task()
def async_create_transactions(entry_id):
    sleep(1)
    bank_entry = BankEntries.objects.filter(pk=entry_id).first()
    if bank_entry: 
        return bank_entry.create_entries()

这可能不是最优雅的解决方案,但在很多情况下它对我来说都是有效的。