Django 1.8.5 和 Celery 的 ImportError
ImportError with Django 1.8.5 and Celery
我正在尝试让 Celery 运行 Django,遵循官方文档和位于此处的视频:https://godjango.com/63-deferred-tasks-and-scheduled-jobs-with-celery-31-django-17-and-redis/
我不知道我做错了什么,但这总是会导致 ImportError。
项目名为"clubmgmt"
"clubmgmt/celery.py" 的内容:
from __future__ import absolute_import
import os
import django
from celery import Celery
from django.conf import settings
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'clubmgmt.settings')
django.setup()
app = Celery('clubmgmt')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
"clubmgmt/__init__.py"
的内容
from __future__ import absolute_import
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from clubmgmt.celery import app as celery_app
任务在名为 "activation"
的应用程序中定义
"activation/tasks.py" 的内容:
from activation.models import Activation
from django.conf import settings
from django.template.loader import render_to_string
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from clubmgmt.celery import app
__author__ = 'jeroenjacobs'
@app.task
def send_activation_mail(activation_pk):
activation = Activation.objects.get(pk=activation_pk)
mail = activation.user.email
msg = MIMEMultipart('alternative')
msg['Subject'] = "Please activate your account"
msg['From'] = settings.SMTP_SENDER_ADDRESS
msg['To'] = mail
...
我总是收到以下错误:
(clubmgmt) > $ python manage.py runserver [±master ●●●]
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/core/management/__init__.py", line 351, in execute_from_command_line
utility.execute()
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/core/management/__init__.py", line 303, in execute
settings.INSTALLED_APPS
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 48, in __getattr__
self._setup(name)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 44, in _setup
self._wrapped = Settings(settings_module)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 92, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "/Users/jeroenjacobs/.pyenv/versions/3.4.3/Python.framework/Versions/3.4/lib/python3.4/importlib/__init__.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2212, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1129, in _exec
File "<frozen importlib._bootstrap>", line 1471, in exec_module
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/clubmgmt/__init__.py", line 5, in <module>
from clubmgmt.celery import app as celery_app
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/clubmgmt/celery.py", line 9, in <module>
django.setup()
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/__init__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/apps.py", line 10, in ready
import activation.handlers
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/handlers.py", line 6, in <module>
from activation.utils import create_or_update_activation
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/utils.py", line 2, in <module>
from activation.tasks import send_activation_mail
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/tasks.py", line 7, in <module>
from clubmgmt.celery import app
ImportError: cannot import name 'app'
谁能解释一下为什么 "app" 无法导入?
顺便说一句:这是在 python 3.4 下测试的。回到 Python 2 不是一个选项,所以请不要建议将此作为解决方案。如果 Celery 与 Python3 不兼容,还有其他选择吗?
问题是 clubmgmt.celery.app
尝试导入 clubmgm.celery.app
导致循环导入。
如果您查看堆栈跟踪 clubmgmt.__init__
导入 clubmgmt.celery.app
,这反过来使 django
运行 成为其设置例程,最终触发 clubmgmt.activation.apps
在某些时候通过 clubmgmt.activation.tasks
再次导入 clubmgmt.celery.app
,同时仍在导入,导致 ImportError
.
从 __init__.py
中删除该导入肯定会解决问题,但如果您仍然需要它,您可以改用 activation/apps.py
来做一些事情。
到目前为止我了解到的一件事是,90% 的时间 ImportError
是由于循环导入,另外 10% 是由于拼写错误或类似的原因。
我正在尝试让 Celery 运行 Django,遵循官方文档和位于此处的视频:https://godjango.com/63-deferred-tasks-and-scheduled-jobs-with-celery-31-django-17-and-redis/
我不知道我做错了什么,但这总是会导致 ImportError。
项目名为"clubmgmt"
"clubmgmt/celery.py" 的内容:
from __future__ import absolute_import
import os
import django
from celery import Celery
from django.conf import settings
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'clubmgmt.settings')
django.setup()
app = Celery('clubmgmt')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
"clubmgmt/__init__.py"
的内容from __future__ import absolute_import
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from clubmgmt.celery import app as celery_app
任务在名为 "activation"
的应用程序中定义"activation/tasks.py" 的内容:
from activation.models import Activation
from django.conf import settings
from django.template.loader import render_to_string
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from clubmgmt.celery import app
__author__ = 'jeroenjacobs'
@app.task
def send_activation_mail(activation_pk):
activation = Activation.objects.get(pk=activation_pk)
mail = activation.user.email
msg = MIMEMultipart('alternative')
msg['Subject'] = "Please activate your account"
msg['From'] = settings.SMTP_SENDER_ADDRESS
msg['To'] = mail
...
我总是收到以下错误:
(clubmgmt) > $ python manage.py runserver [±master ●●●]
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/core/management/__init__.py", line 351, in execute_from_command_line
utility.execute()
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/core/management/__init__.py", line 303, in execute
settings.INSTALLED_APPS
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 48, in __getattr__
self._setup(name)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 44, in _setup
self._wrapped = Settings(settings_module)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 92, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File "/Users/jeroenjacobs/.pyenv/versions/3.4.3/Python.framework/Versions/3.4/lib/python3.4/importlib/__init__.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2212, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1129, in _exec
File "<frozen importlib._bootstrap>", line 1471, in exec_module
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/clubmgmt/__init__.py", line 5, in <module>
from clubmgmt.celery import app as celery_app
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/clubmgmt/celery.py", line 9, in <module>
django.setup()
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/__init__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/apps.py", line 10, in ready
import activation.handlers
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/handlers.py", line 6, in <module>
from activation.utils import create_or_update_activation
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/utils.py", line 2, in <module>
from activation.tasks import send_activation_mail
File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/tasks.py", line 7, in <module>
from clubmgmt.celery import app
ImportError: cannot import name 'app'
谁能解释一下为什么 "app" 无法导入?
顺便说一句:这是在 python 3.4 下测试的。回到 Python 2 不是一个选项,所以请不要建议将此作为解决方案。如果 Celery 与 Python3 不兼容,还有其他选择吗?
问题是 clubmgmt.celery.app
尝试导入 clubmgm.celery.app
导致循环导入。
如果您查看堆栈跟踪 clubmgmt.__init__
导入 clubmgmt.celery.app
,这反过来使 django
运行 成为其设置例程,最终触发 clubmgmt.activation.apps
在某些时候通过 clubmgmt.activation.tasks
再次导入 clubmgmt.celery.app
,同时仍在导入,导致 ImportError
.
从 __init__.py
中删除该导入肯定会解决问题,但如果您仍然需要它,您可以改用 activation/apps.py
来做一些事情。
到目前为止我了解到的一件事是,90% 的时间 ImportError
是由于循环导入,另外 10% 是由于拼写错误或类似的原因。