2011-09-08 17 views
5

Voglio eseguire un'attività di Django - Celery con la gestione manuale delle transazioni, ma sembra che le annotazioni non si sovrappongano.Django - Celery: @transaction e @task non si impilano

ad es.

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

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

risultati in

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

mentre i risultati di ordine annotazione inversa a

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

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

ha senso, ma sto avendo problemi a trovare una bella soluzione. I documenti di Django non menzionano alternative all'annotazione e non voglio creare una classe per ogni attività di sedano quando non ne ho bisogno.

Qualche idea?

risposta

8

precedenza sedano avevano una certa magia, dove una serie di argomenti di parole chiave predefinite sono state approvate al compito, se li ha accettati.

Dalla versione 2.2 è possibile disattivare questo comportamento, ma il più semplice è quello di importazione del task decoratore da celery.task invece di celery.decorators:

from celery.task import task 

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

Il modulo decorators è deprecato e sarà completamente rimosso in 3.0, e lo stesso per gli "argomenti delle parole chiave magiche"

Nota: Per le classi di attività personalizzate è necessario impostare l'attributo accept_magic_kwargs su False:

class MyTask(Task): 
    accept_magic_kwargs = False 

Nota 2: Assicurarsi che i decoratori personalizzati conserva il nome della funzione utilizzando functools.wraps, altrimenti l'operazione si concluderà con il nome sbagliato.

+0

Questo è esattamente quello che speravo! Grazie! – Rob

6

Il decoratore di attività genera un class x(Task) dalla funzione con il metodo run come destinazione. Suggerisci di definire la classe e decorare il metodo.

es .: testato

class pong(Task): 
    ignore_result = True 

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

Speravo di trovare un modo non di classe per farlo, ma immagino che questa sia l'alternativa migliore. Grazie! – Rob

Problemi correlati