Celery: タスクの結果をMySQLで確認する

PYPI:

django-celery-results = "^2.5.0"

settings:

1
2
3
CELERY_RESULT_BACKEND = "django-db"
CELERY_RESULT_EXTENDED = True
INSTALLED_APPS += ["django_celery_results"]

Database Result Backend

It seems that you are using Django and Celery to run asynchronous tasks and store the results in a database. One possible reason why the result data is always null is that you are not returning anything from your task function². For example, if your task function looks like this:

1
2
3
@app.task
def add(x, y):
    z = x + y

Then the result data will be null because you are not returning z. To fix this, you need to add a return statement at the end of your task function:

1
2
3
4
@app.task
def add(x, y):
    z = x + y
    return z

Another possible reason is that you are not using the correct backend to store the results. You need to specify the CELERY_RESULT_BACKEND setting in your settings.py file and make sure it matches the database you are using¹. For example, if you are using MySQL, you need to set something like this:

1
CELERY_RESULT_BACKEND = 'db+mysql://user:password@host/database'

You can also use django_celery_results to store the results in a Django model²³. In that case, you need to install django_celery_results and add it to your INSTALLED_APPS setting:

1
2
3
4
INSTALLED_APPS = (
    ...,
    'django_celery_results',
)

Then you need to set the CELERY_RESULT_BACKEND to use the Django model:

1
CELERY_RESULT_BACKEND = 'django-db'

You also need to run migrations to create the table for storing the results:

1
python manage.py migrate django_celery_results

Then you can access the results from the TaskResult model by filtering by task_id or task_name²³. For example:

1
2
3
4
5
from django_celery_results.models import TaskResult

tr = TaskResult.objects.get(task_id='2781413b-282e-4de8-b134-b338b592ad02')
print(tr.status) # 'SUCCESS'
print(tr.result) # '11'

I hope this helps. Do you have any other questions?

ソース: Bing との会話 2023/4/12

AsyncResult.result が null

Celery AsyncResult is a class that represents the result of a task. You can use it to check the status and result of a task by passing the task id to its constructor¹. For example:

1
2
3
4
5
6
from tasks import add
from celery.result import AsyncResult

res = AsyncResult('05f3f783-a538-45ed-89e3-c836a2623e8a')
print(res.state) # 'SUCCESS'
print(res.result) # 9

However, there are some possible reasons why the result may be always null. One reason is that you are not using a backend to store the results. You need to specify the CELERY_RESULT_BACKEND setting in your settings.py file and make sure it matches the database or message broker you are using². Another reason is that you are not setting the CELERY_TASK_TRACK_STARTED setting to True. This setting enables Celery to update the task status to STARTED when it begins execution². Otherwise, the status may remain PENDING until the result is ready³. A third reason is that you are not waiting for the task to finish before checking the result. You can use the get method of AsyncResult to block until the result is available, or use the ready method to check if the result is ready¹. For example:

1
2
3
4
5
6
7
8
9
from tasks import add
from celery.result import AsyncResult

res = AsyncResult('05f3f783-a538-45ed-89e3-c836a2623e8a')
if res.ready():
    print(res.state) # 'SUCCESS'
    print(res.result) # 9
else:
    print("Task is not ready yet")

I hope this helps. Do you have any other questions?

ソース: Bing との会話 2023/4/12