python - 调用异步任务 celery 时引发异常 : "NameError: global name * is not defined"

标签 python django django-models celery

执行异步任务时 celery 引发异常

#case where error is thrown
send_registration_email.delay("test", "test@gmail.com", {})

当我通过省略 celery 执行代码时,不会出现此错误

#case where code is executed correctly
send_registration_email("test", "test@gmail.com", {})

如何使用 celery 执行异步任务,从而消除此错误?

错误

[2015-10-12 14:50:57,176: ERROR/MainProcess] Task tasks.core.email.send_registration_email[5f96bee3-9df7-42ce-b726-c7086e82b954] raised unexpected: NameError("global name 'Mailer' is not defined",)
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/celery/app/trace.py", line 240, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/celery/app/trace.py", line 438, in __protected_call__
    return self.run(*args, **kwargs)
  File "/srv/www/compare/htdocs/tasks/core/email.py", line 6, in send_registration_email
    @shared_task
NameError: global name 'Mailer' is not defined

celery 任务

# email.py 
from __future__ import absolute_import
from celery import shared_task
from utilities.helpers.mailer import Mailer

@shared_task
def send_registration_email(email_type="", recipient="", data={}):
    Mailer.send_email(email_type, recipient, data)

邮件类

# mailer.py
from __future__ import absolute_import
from django.core.mail.message import EmailMultiAlternatives
from django.template.loader import get_template


class Mailer():

    @staticmethod
    def send_email(email_type="", recipient="", data={}):
        try:
            email = Mailer.create_email(email_type, recipient, data)
            email.send()
            return True
        except Exception as e:
            return False

    @classmethod
    def create_email(self, email_type, recipient, data):
        subject = ""
        message = ""
        sender_email = "mailgun@xxx.mailgun.org"

        if email_type == "test":
            subject = "Test subject"
            content_html = "<html><body><h1>Test</h1></body></html>"

        email = EmailMultiAlternatives(subject, None, sender_email, [recipient])
        email.attach_alternative(content_html, "text/html")
        return email

最佳答案

您需要重新启动工作器才能看到工作器实例中反射(reflect)的文件更改。 Celery 不会监视文件更改,因此如果您在工作线程运行时更改任何文件,则需要重新启动工作线程。

出于开发目的,可以使用auto reloading来回避这个问题。特点:

When auto-reload is enabled the worker starts an additional thread that watches for changes in the file system. New modules are imported, and already imported modules are reloaded whenever a change is detected, and if the prefork pool is used the child processes will finish the work they are doing and exit, so that they can be replaced by fresh processes effectively reloading the code.

这是一项实验性功能,只能在开发环境中使用

关于python - 调用异步任务 celery 时引发异常 : "NameError: global name * is not defined",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33081993/

相关文章:

django 查询集 : retrieving/extracting objects with different primary keys (from a list)

python - 将 django 过滤器编译成变量并在运行时执行?

python - 根据列(字符串)对 pandas 中的 CSV 进行排序

python - HttpResponseRedirect问题

python - 基于 Python Web 框架中的 Accept header 路由请求

python - 尝试传递字符串以通过 Django Rest Framework url 进行查询

python - 在 Django Admin 中,选项可以依赖于其他值吗?

Django ORM 按过滤器排序

python - 使用方法调用在 Python 中格式化多行

python - 将模型之外的字段组合到预先存在的数据库中的正确方法