Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing a task id for each celery task in database

I have using celery with MySQL. I want to to store the task id as a plain integer in a database or in a variable of celery task. How can I do that?

like image 302
pynovice Avatar asked Mar 04 '13 10:03

pynovice


People also ask

How do I get task ID in the celery task?

To obtain the value of task_id you first have to create an instance of that class, afterwards accessing async_result_instance. task_id will return you the real id. In your updated code: (Code not tested since I don't have celery installed.)

Is celery task ID unique?

Answer: Yes, but make sure it's unique, as the behavior for two tasks existing with the same id is undefined.

Where are Celery tasks stored?

In Celery, a result back end is a place where, when you call a Celery task with a return statement, the task results are stored. Choosing the right results back end can potentially save you hours of pain later.

Can a celery task call another task?

To answer your opening questions: As of version 2.0, Celery provides an easy way to start tasks from other tasks. What you are calling "secondary tasks" are what it calls "subtasks".


2 Answers

Why not create a celery task model, and save a celery task id to that model?

class CeleryModel(models.Model):
    celery_task_id = models.CharField(max_length = 50, unique=True)

Then:

def some_celery_task():
    result = celery_task.delay()
    celery_task = CeleryModel(celery_task_id = result.id)
    celery_task.save() # added save line

Your integer value would then be: celery_task.id to correspond with the actual, unique celery_task_id.

UPDATE: another way ...

First python manage.py inspectdb > inspectdb.py. Inside that file you will find:

class CeleryTaskmeta(models.Model):
    id = models.IntegerField(primary_key=True)
    task_id = models.CharField(max_length=765, unique=True)
    status = models.CharField(max_length=150)
    result = models.TextField(blank=True)
    date_done = models.DateTimeField()
    traceback = models.TextField(blank=True)
    hidden = models.IntegerField()
    meta = models.TextField(blank=True)
    class Meta:
        db_table = u'celery_taskmeta'

Next, python manage.py startapp celery_model. Put this file in the models.py file. I use south, so my final step would be python manage.py convert_app celery_model. However, its unnecessary. Now you have django level access to this celery datatable, and can read the primary key for each task as your integer value. E.g

>>> ct = CeleryTaskmeta.objects.get(id=1)
>>> for k,v in ct.__dict__.items(): print k,v
... 
status SUCCESS
task_id 2fa95f24-7640-434c-9fef-0732ac1d23c7
date_done 2013-02-17 19:22:56+00:00
traceback None
_state <django.db.models.base.ModelState object at 0x10263fa90>
meta eJxrYKotZAzlSM7IzEkpSs0rZIotZC7WAwBREgb9
result gAJLBC4=
hidden 0
id 1

Someone clever would know how to make your CeleryTaskmeta a read-only model because I don't think you would want to tamper with the datatable.

UPDATE: to the last part of your question:

>>> from celerytest.tasks import add
>>> result = add.delay()
>>> result.int_id = 1
>>> for k,v in result.__dict__.items(): print k,v
...
parent None
app <Celery default:0x10264df10>
task_name celerytest.tasks.add
int_id 1
id 01503afd-d196-47af-8e10-e7dc06603cfc
backend <djcelery.backends.database.DatabaseBackend object at 0x1026842d0>
like image 158
Cole Avatar answered Sep 18 '22 20:09

Cole


To get the celery task ID when the task is started I do the following:

process_task = my_task.apply_async(args=[args])
task_id = process_task.task_id

where my_task is a method within tasks.py

like image 34
hellsgate Avatar answered Sep 21 '22 20:09

hellsgate