2011-09-08 17 views
5

手動トランザクション管理でDjango - Celeryタスクを実行したいのですが、注釈がスタックしないようです。Django - Celery:@transactionと@taskはスタックしません

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

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

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

結果

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

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

で逆の注釈順序結果ながら、それは理にかなって、私はトラブル素敵な回避策を見つけることを抱えています。 Djangoのドキュメントにはアノテーションの代替案は記載されておらず、セロリのタスクごとにクラスを作成する必要はありません。

アイデア?

答えて

8

以前セロリは、それが彼らを受け入れた場合、デフォルトのキーワード引数 のセットがタスクに渡されたいくつかの魔法を持っていました。あなたは、この動作を無効にすることができ、バージョン2.2以来

が、最も簡単で にあるcelery.task代わりのcelery.decoratorsからtaskデコレータをインポートします。

from celery.task import task 

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

decoratorsモジュールが廃止されており、完全に3.0で削除されます、 "magicキーワード引数"についても同じ

注: カスタムタスククラスの場合は、accept_magic_kwargs属性をFalseに設定する必要があります。

class MyTask(Task): 
    accept_magic_kwargs = False 

注2:そうでない場合は、タスクが間違った名前で終わるだろう、カスタムデコレータはfunctools.wrapsを使用して関数の名前を保持していることを確認します。

+0

これはまさに私が望んでいたものです!ありがとう! – Rob

6

タスクデコレータは、runメソッドをターゲットとして関数からclass x(Task)を生成します。あなたはクラスを定義し、メソッドを装飾することを提案する。

テストされていない例えば:

class pong(Task): 
    ignore_result = True 

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

これを行うにはクラス以外の方法があると考えていましたが、これが最良の選択肢だと思います。ありがとう! – Rob

関連する問題