pythondjangocelerypythonanywhere

django celery: object has no attribute 'delay_on_commit'


django 4.2 with celery 5.5.1

launching a celery task from a django view sometimes causes "'generate_report' object has no attribute 'delay_on_commit'"

# tasks.py
from celery import shared_task

@shared_task
def generate_report(data):
    # Code to generate report
    ...

# django view
def testview(request):
    from tasks import generate_report

    generate_report.delay_on_commit("mytestdata")

    return render(request, "simple_page.html")

This happens on some deployments, but not on all. And when it happens, a server (webapp) reboot solves the issue. Moving the "generate_report" import to the top of the file also did not help.

Note: Code is deployed on pythonanywhere.com with several celery workers running in "always on" tasks.

Update 24/4/2025: The issue happened again today. dir(generate_report) gave this result:

['AsyncResult', 'MaxRetriesExceededError', 'OperationalError', 'Request', 'Strategy', 'annotations', 'bound', 'call', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'header', 'init', 'init_subclass', 'le', 'lt', 'module', 'name', 'ne', 'new', 'qualname', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'trace', 'v2_compat', 'weakref', 'wrapped', '_app', '_backend', '_decorated', '_default_request', '_exec_options', '_get_app', '_get_exec_options', '_get_request', 'abstract', 'acks_late', 'acks_on_failure_or_timeout', 'add_around', 'add_to_chord', 'add_trail', 'after_return', 'annotate', 'app', 'apply', 'apply_async', 'backend', 'before_start', 'bind', 'chunks', 'default_retry_delay', 'delay', 'expires', 'from_config', 'ignore_result', 'map', 'max_retries', 'name', 'on_bound', 'on_failure', 'on_replace', 'on_retry', 'on_success', 'pop_request', 'priority', 'push_request', 'rate_limit', 'reject_on_worker_lost', 'replace', 'request', 'request_stack', 'resultrepr_maxsize', 'retry', 'run', 's', 'send_event', 'send_events', 'serializer', 'shadow_name', 'si', 'signature', 'signature_from_request', 'soft_time_limit', 'starmap', 'start_strategy', 'store_eager_result', 'store_errors_even_if_ignored', 'subtask', 'subtask_from_request', 'throws', 'time_limit', 'track_started', 'trail', 'typing', 'update_state']


Solution

  • This turned out to be a misconfiguration, not loading .env where it should have been loaded.

    .env is loaded in settings.py (django)

    But .env was not loaded in celery.py as it was assumed to be loaded already. This seems not always the case.  Sometimes celery.py is run from an _init_ script while .env is not loaded.

    This causes celery to run without a valid broker URL, which causes network issues. These network issues cause problems for .delay() and .delay_on_commit()