Django - Celery:@transaction和@task不叠加

时间:2011-09-08 15:03:16

标签: django celery django-celery

我想用手动事务管理来运行Django-Celery任务,但似乎注释没有堆栈。

e.g。

def ping():
    print 'ping'
    pong.delay('arg')

@task(ignore_result=True)
@transaction.commit_manually()
def pong(arg):
    print 'pong: %s' % arg
    transaction.rollback()

结果

TypeError: pong() got an unexpected keyword argument 'task_name'

而反向注释顺序导致

---> 22     pong.delay('arg')

AttributeError: 'function' object has no attribute 'delay'

这很有道理,但我找不到一个好的解决方法。 Django文档没有提到注释的替代品,我不想在不需要的时候为每个芹菜任务创建一个类。

有什么想法吗?

2 个答案:

答案 0 :(得分:8)

以前Celery在一组默认关键字参数中有一些魔力 如果它接受了它们就被传递给任务。

从版本2.2开始,您可以禁用此行为,但最简单的方法是 从task而不是celery.task导入celery.decorators装饰器:

from celery.task import task

@task
@transaction.commit_manually
def t():
    pass

{@ 1}}模块已弃用,将在3.0中完全删除, 和“魔术关键词参数”

相同

注意: 对于自定义任务类,您应将decorators属性设置为False:

accept_magic_kwargs

注意2:确保您的自定义装饰器使用class MyTask(Task): accept_magic_kwargs = False 保留函数的名称,否则任务将以错误的名称结束。

答案 1 :(得分:6)

任务装饰器使用class x(Task)方法作为目标从您的函数生成run。建议你定义类并装饰方法。

未经测试,例如:

class pong(Task):
  ignore_result = True

  @transaction.commit_manually()
  def run(self,arg,**kwargs):
    print 'pong: %s' % arg
    transaction.rollback()