Django,ImportError:无法导入名称 Celery,可能的循环导入?
Posted
技术标签:
【中文标题】Django,ImportError:无法导入名称 Celery,可能的循环导入?【英文标题】:Django, ImportError: cannot import name Celery, possible circular import? 【发布时间】:2013-11-24 11:00:33 【问题描述】:我在这里浏览了这个例子:
http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html
我所有的任务都在名为 tasks.py 的文件中。
更新 celery 并从示例 django 添加文件后,无论我尝试什么,都会引发以下错误:
ImportError: cannot import name Celery
问题可能是由以下原因引起的吗?
app.autodiscover_tasks(settings.INSTALLED_APPS, related_name='tasks')
因为它会遍历所有具有以下导入的 tasks.py 文件。
from cloud.celery import app
cloud/celery.py:
from __future__ import absolute_import
import os, sys
from celery import Celery
from celery.schedules import crontab
from django.conf import settings
BROKER_URL = 'redis://:PASSWORD@localhost'
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cloud.settings')
app = Celery('cloud', broker=BROKER_URL)
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(settings.INSTALLED_APPS, related_name='tasks')
if "test" in sys.argv:
app.conf.update(
CELERY_ALWAYS_EAGER=True,
)
print >> sys.stderr, 'CELERY_ALWAYS_EAGER = True'
CELERYBEAT_SCHEDULE =
'test_rabbit_running':
"task": "retail.tasks.test_rabbit_running",
"schedule": 3600, #every hour
,
[..]
app.conf.update(
CELERYBEAT_SCHEDULE=CELERYBEAT_SCHEDULE
)
retail/tasks.py:
from cloud.celery import app
import logging
from celery.utils.log import get_task_logger
logger = get_task_logger('tasks')
logger.setLevel(logging.DEBUG)
@app.task
def test_rabbit_running():
import datetime
utcnow = datetime.datetime.now()
logger.info('CELERY RUNNING')
当我尝试访问无效的 url 时发生错误,例如 /foobar。
这是完整的追溯:
Traceback (most recent call last):
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 126, in handle_request
respiter = self.wsgi(environ, resp.start_response)
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 255, in __call__
response = self.get_response(request)
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 178, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 220, in handle_uncaught_exception
if resolver.urlconf_module is None:
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 342, in urlconf_module
self._urlconf_module = import_module(self.urlconf_name)
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/opt/src/slicephone/cloud/cloud/urls.py", line 52, in
urlpatterns += patterns('', url(r'^search/', include('search.urls')))
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 25, in include
urlconf_module = import_module(urlconf_module)
File "/opt/virtenvs/django_slice/local/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/opt/src/slicephone/cloud/search/urls.py", line 5, in
from handlers import SearchHandler
File "/opt/src/slicephone/cloud/search/handlers.py", line 15, in
from places import handlers as placeshandler
File "/opt/src/slicephone/cloud/places/handlers.py", line 23, in
import api as placesapi
File "/opt/src/slicephone/cloud/places/api.py", line 9, in
from djapi import *
File "/opt/src/slicephone/cloud/places/djapi.py", line 26, in
from tasks import add_single_place, add_multiple_places
File "/opt/src/slicephone/cloud/places/tasks.py", line 2, in
from cloud.celery import app
File "/opt/src/slicephone/cloud/cloud/celery.py", line 4, in
from celery import Celery
File "/opt/src/slicephone/cloud/cloud/celery.py", line 4, in
from celery import Celery
ImportError: cannot import name Celery
【问题讨论】:
请提供完整的回溯,而不仅仅是最后一行 @user1252307 请将您的答案标记为已接受。 【参考方案1】:将以下行添加到 cloud/celery.py:
import celery
print celery.__file__
给了我文件本身,而不是库中的 celery 模块。将 celery.py 重命名为 celeryapp.py 并调整导入后,所有错误都消失了。
注意:
这导致启动工人的变化:
celery worker --app=cloud.celeryapp:app
对于那些运行 celery==3.1.2 并收到此错误的用户:
TypeError: unpack_from() argument 1 must be string or read-only buffer, not memoryview
应用此处提到的补丁:https://github.com/celery/celery/issues/1637
【讨论】:
并且不要忘记删除目录下编译好的cloud/celery.pyc。如果没有,您将继续收到错误消息。 我看到了这个确切的错误,我不明白为什么在使用from __future__ import absolute_import
时需要重命名文件,但这就是我所做的。
@scum 感谢您的提醒。
聪明的解决方案,我不知道为什么开发者选择 celery.py 作为默认名称,造成这个问题并且不得不到处依赖from __future__ import absolute_import
。
除celery
外不能命名,否则无法通过celery worker -A src
调用【参考方案2】:
使用 Django 1.7.5、Celery 3.1.17 和 Python 2.7.6,我发现我仍然收到这些 ImportError: cannot import name Celery
。但仅在 PyCharm 4.0.4 下运行测试时。
我发现一个解决方案不依赖from __future__ import absolute_import
,如First Steps with Django 中所述。相反,我将proj/proj/celery.py
重命名为proj/proj/celery_tasks.py
,然后将__init__.py
的内容更改为匹配:from .celery_tasks import app as celery_app
。不再有多个名为 celery.py
的文件实例会导致导入混淆,这似乎是一种更简单的方法。
【讨论】:
这正是我为消除代码和我自己的任何混淆所做的。 以上内容在 django 1.8 中为我工作,但我将from __future__ import absolute_import
留在了那里并且工作正常。虽然我还必须rm *.pyc
并重新启动开发服务器。
我遇到了同样的错误,但体验略有不同。在 PyCharm 2017.2 中,我开始收到有关导入不起作用的错误。原来这是因为我在命令行上使用charm
命令启动了PyCharm ... 坏主意。该命令行继承自 shell 的环境,在 shell 上,我将默认的 Python 3.6 和 PYTHONPATH
泄漏到 PyCharm 中的 Python2 项目中。解决方案是在终端之外启动 PyCharm,我的问题就消失了。
这正是我的解决方案。 from __future__ import absolute_import
不起作用。【参考方案3】:
遇到同样的错误
我的 celery 设置文件名 (celery.py) 与“celery”包冲突...
所以在执行此操作时-> from celery import Celery , 它引发了错误-无法导入名称 Celery
解决方案->只需将“celery.py”更改为“celery-settings.py”之类的其他内容
【讨论】:
还要删除最终导致我的问题的 celery.pyc。【参考方案4】:为我工作(在服务器中部署后的一些错误): 从项目中删除所有 *.pyc 文件并重新启动他。
【讨论】:
尝试了好几个小时。在 MacOs 中构建了整个代码,然后尝试在 Windows 上运行相同的应用程序,但我只有循环导入。删除了所有 *.pyc 文件,现在它工作了!!!谢谢【参考方案5】:您是否添加了行:
from __future__ import absolute_import
到cloud/celery.py
模块的顶部?
在此处阅读示例的细分: http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html
【讨论】:
【参考方案6】:我遇到了同样的错误。原来我的 Celery 版本有问题。我升级到 3.1,celeryd 现在已弃用此版本 (http://celery.readthedocs.org/en/latest/whatsnew-3.1.html)。所以我不得不降级到 3.0.19 版本,这是该项目之前使用的稳定版本,到目前为止它运行良好。
pip install celery==3.0.19
无论如何,如果你不想降级,3.1版本中celeryd的替代品是celery worker。在这里查看更多信息:http://celery.readthedocs.org/en/latest/userguide/workers.html。
希望这会有所帮助! :)
【讨论】:
【参考方案7】:对于想知道导致此错误的原因的人: 刚刚遇到这个问题,后来发现问题---sys.path. 也许你像我一样添加一些到 sys.path 的路径,我在 manage.py 中添加下面的代码,
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
SRC_PATH = os.path.join(ROOT_PATH, 'src')
CONF_PATH = os.path.join(ROOT_PATH, 'conf')
sys.path.insert(0, SRC_PATH)
sys.path.insert(0, CONF_PATH)
所以,from celery import Celery
会先在 SRC_PATH
和 CONF_PATH
中搜索 celery,这就是问题所在。
改成
sys.path.append(SRC_PATH)
sys.path.append(CONF_PATH)
它将首先在 python 的 lib
和 site-packages
中搜索。完美解决。
【讨论】:
谢谢,这是我的问题 :-)【参考方案8】:我遇到过类似的问题: 从芹菜进口芹菜 ImportError:无法从“芹菜”中导入名称“芹菜”
解决此问题的另一种简单方法: 如果您的包在 celery.py 中有 celery 配置,这就是导致问题的原因。 将其重命名为 celery_settings.py
【讨论】:
如果你重命名它你就不能运行它celery worker -A src
【参考方案9】:
请注意,较旧的 Django 项目在与项目目录相同的目录中具有 manage.py
脚本。也就是结构是这样的:
- proj/
- proj/__init__.py
- proj/celery.py
- proj/urls.py
- proj/manage.py
- proj/settings.py
而不是这个:
- proj/
- proj/__init__.py
- proj/celery.py
- proj/settings.py
- proj/urls.py
- manage.py
在这种情况下,您只需将 celery.app
文件重命名为不同的名称,如上面接受的答案中所建议的 celeryapp.py
。
【讨论】:
【参考方案10】:我遇到了同样的错误。
似乎from __future__ import absolute_import
不适用于 Python 2.6.1,仍然不会引发错误。
升级到 Python 2.7.5 并且可以正常工作。
【讨论】:
以上是关于Django,ImportError:无法导入名称 Celery,可能的循环导入?的主要内容,如果未能解决你的问题,请参考以下文章
ImportError:升级到 Django 4.0 后无法从“django.conf.urls”导入名称“url”
Django ImportError:无法导入名称 get_permission_codename
Django 上的 MakeMigration 错误 - ImportError:无法从“django.db.models”导入名称“FieldDoesNotExist”
由于 ImportError,Celery Django 部署因 Elastic Beanstalk 失败:无法导入名称“Celery”(ElasticBeanstalk::ExternalInvoc