2011-09-08 14 views
5

Quiero ejecutar una tarea Django - Apio con gestión manual de transacciones, pero parece que las anotaciones no se acumulan.Django - Apio: @transaction y @task no apilan

p. Ej.

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

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

resultados en

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

mientras que los resultados de la orden de anotación inversa en

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

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

tiene sentido, pero estoy teniendo problemas para encontrar un buen solución. Los documentos de Django no mencionan alternativas a la anotación, y no quiero hacer una clase para cada tarea de apio cuando no la necesito.

¿Alguna idea?

Respuesta

8

Previamente apio tenían un poco de magia, donde un conjunto de argumentos de palabra clave por defecto se pasa a la tarea si los acepta.

Desde la versión 2.2 se puede desactivar este comportamiento, pero la más sencilla es importar el task decorador de celery.task en lugar de celery.decorators:

from celery.task import task 

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

El módulo decorators es obsoleto y se eliminará por completo en 3.0, y lo mismo para los "argumentos de palabras clave mágicas"

Nota: Para las clases de tareas personalizadas, debe establecer el atributo accept_magic_kwargs en False:

class MyTask(Task): 
    accept_magic_kwargs = False 

Nota 2: Asegúrese de que sus decoradores personalizados conserva el nombre de la función utilizando functools.wraps, de lo contrario la tarea va a terminar con el nombre equivocado.

+0

¡Esto es exactamente lo que esperaba! ¡Gracias! – Rob

6

El decorador de tareas genera un class x(Task) de su función con el método run como su objetivo. Te sugiero que definas la clase y decores el método.

por ejemplo .: No comprobado

class pong(Task): 
    ignore_result = True 

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

Tenía la esperanza de encontrar una forma no de clase para hacerlo, pero creo que esta es la mejor alternativa. ¡Gracias! – Rob

Cuestiones relacionadas