我有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函数和其他副作用。
答案 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()
这可能不是最优雅的解决方案,但在很多情况下它对我来说都是有效的。