带有Celery的Django-找不到现有对象 [英] Django with Celery - existing object not found

查看:104
本文介绍了带有Celery的Django-找不到现有对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在从另一个芹菜任务执行芹菜任务时遇到问题。

I am having problem with executing celery task from another celery task.

这里是有问题的代码段(数据对象已存在于数据库中,其属性只是在内部更新finalize_data函数):

Here is the problematic snippet (data object already exists in database, its attributes are just updated inside finalize_data function):

def finalize_data(data):
    data = update_statistics(data)
    data.save()
    from apps.datas.tasks import optimize_data
    optimize_data.delay(data.pk)

@shared_task
def optimize_data(data_pk):
    data = Data.objects.get(pk=data_pk)
    #Do something with data

optimize_data函数中的Get调用失败,并显示不存在数据匹配查询。

Get call in optimize_data function fails with "Data matching query does not exist."

如果我在finalize_data函数中调用pk函数进行检索,则效果很好。如果我将celery任务调用延迟了一段时间,它也可以正常工作。

If I call the retrieve by pk function in finalize_data function it works fine. It also works fine if I delay the celery task call for some time.

此行:

optimize_data.apply_async((data.pk,), countdown=10)

而不是

optimize_data.delay(data.pk)

工作正常。但是我不想在代码中使用hack。 .save()调用是否可能异步阻止对该行/对象的访问?

works fine. But I don't want to use hacks in my code. Is it possible that .save() call is asynchronously blocking access to that row/object?

推荐答案

我猜您的调用方在芹菜开始处理任务之前尚未提交的事务中。因此,芹菜找不到记录。这就是为什么添加倒数计时使其有效的原因。

I'm guessing your caller is inside a transaction that hasn't committed before celery starts to process the task. Hence celery can't find the record. That is why adding a countdown makes it work.

在您的示例中,倒数1秒的效果可能与10秒的倒数效果一样。我在整个代码中都使用了1秒的倒计时来解决此问题。

A 1 second countdown will probably work as well as the 10 second one in your example. I've used 1 second countdowns throughout code to deal with this issue.

另一种解决方案是停止使用事务。

Another solution is to stop using transactions.

这篇关于带有Celery的Django-找不到现有对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆