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

Rob*_*Rob 5 django celery django-celery

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

例如

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

@task(ignore_result=True)
@transaction.commit_manually()
def pong(arg):
    print 'pong: %s' % arg
    transaction.rollback()
Run Code Online (Sandbox Code Playgroud)

结果是

TypeError: pong() got an unexpected keyword argument 'task_name'
Run Code Online (Sandbox Code Playgroud)

而反向注释顺序导致

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

AttributeError: 'function' object has no attribute 'delay'
Run Code Online (Sandbox Code Playgroud)

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

有任何想法吗?

ask*_*sol 8

以前Celery有一些魔力,如果它接受了一组默认关键字参数就会传递给任务.

自2.2版本,你可以禁用此行为,但最简单的是导入task从装饰celery.task,而不是celery.decorators:

from celery.task import task

@task
@transaction.commit_manually
def t():
    pass
Run Code Online (Sandbox Code Playgroud)

decorators模块已弃用,将在3.0中完全删除,"魔术关键字参数"也相同

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

class MyTask(Task):
    accept_magic_kwargs = False
Run Code Online (Sandbox Code Playgroud)

注意2:确保您的自定义装饰器保留使用的函数名称functools.wraps,否则任务将以错误的名称结束.


Mat*_*ttH 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()
Run Code Online (Sandbox Code Playgroud)