如何使用transaction.on_commit编写Celery组或链

问题描述 投票:0回答:1

我正在使用django 3.0.2,python 3.6.6,celery 4.3.0和redis服务器4.0.9。我想创建一些链和成组的任务,这些模型在保存模型后运行(transaction.on_commit)。我可以使单个任务以这种方式工作,但是我似乎无法接受正确的咒语以使组或链使用transaction.on_commit。

Sidebar:在使用transaction.on_commit时,我将celery Task类扩展为“隐藏”兰巴舞,因为我总是必须查找正确的格式-有关详细信息,请参见https://browniebroke.com/making-celery-work-nicely-with-django-transactions /。在我的代码中,我使用task.delay_on_commit替换transaction.on_commit和lambda。

回到主要故事。我尝试了这段代码,但失败了,说任务中的对象查询不存在。

jobs = group(tasks.clean_document_image.delay_on_commit(self.document_id, key, values[key]) for key in values).apply_async()

clean_document_image拍摄上载的图像(document_id对象的FileField),并创建具有不同大小的图像的多个副本(值字典中的键是副本的宽度,而值字典中的值只是大小-例如,拇指,xsmall,xxxlarge等)。请注意,我尝试将组中的每个元素延迟到保存FileField的事务完成为止。

[当我运行该组的“模拟”时,它可以按预期工作,带有FileField的对象已保存,带有document_i的查找起作用。

for key in values:
    tasks.clean_document_image.delay_on_commit(self.document_id, key, values[key])

创建一组直到保存django对象才开始的任务的rght方法是什么?换句话说,如何将transaction.on_commit合并到一组任务中?

谢谢!

标记

python django celery django-celery celery-task
1个回答
0
投票

我发现这可行:

from django.db import transaction
transaction.on_commit(lambda: chain(task1.si(args), 
                                    task2.si(args), 
                                    task3.si(args)).delay())

。si用于不返回值作为链中下一个任务的输入的任务。如果希望task2的任务使用task1的输出,请使用task1.s(args)。 task2的第一个参数必须是task1的输出值。

© www.soinside.com 2019 - 2024. All rights reserved.