【问题标题】:ImportError being generated when trying to run django-celery worker process尝试运行 django-celery 工作进程时生成 ImportError
【发布时间】:2013-07-30 11:06:32
【问题描述】:

我正在尝试将 django-celery 集成到现有网站中,但遇到了一个似乎无法修复的错误。

就上下文而言,我通过Django first steps 测试项目成功,即一切正常。

现在,在我现有的项目中,我无法让 celery worker 从命令行运行:

manage.py celery worker --loglevel=info --settings=myproject.settings.dev_settings

当我运行时,我得到以下堆栈跟踪和错误:

Traceback (most recent call last):
  File "C:\sites\corecrm\manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 453, in execute_from_command_line
    utility.execute()
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Python27\lib\site-packages\djcelery\management\commands\celery.py", line 22, in run_from_argv
    ['%s %s' % (argv[0], argv[1])] + argv[2:],
  File "C:\Python27\lib\site-packages\celery\bin\celery.py", line 901, in execute_from_commandline
    super(CeleryCommand, self).execute_from_commandline(argv)))
  File "C:\Python27\lib\site-packages\celery\bin\base.py", line 187, in execute_from_commandline
    return self.handle_argv(prog_name, argv[1:])
  File "C:\Python27\lib\site-packages\celery\bin\celery.py", line 893, in handle_argv
    return self.execute(command, argv)
  File "C:\Python27\lib\site-packages\celery\bin\celery.py", line 868, in execute
    return cls(app=self.app).run_from_argv(self.prog_name, argv)
  File "C:\Python27\lib\site-packages\celery\bin\celery.py", line 148, in run_from_argv
    return self(*args, **options)
  File "C:\Python27\lib\site-packages\celery\bin\celery.py", line 118, in __call__
    ret = self.run(*args, **kwargs)
  File "C:\Python27\lib\site-packages\celery\bin\celery.py", line 220, in run
    return self.target.run(*args, **kwargs)
  File "C:\Python27\lib\site-packages\celery\bin\celeryd.py", line 153, in run
    return self.app.Worker(**kwargs).run()
  File "C:\Python27\lib\site-packages\celery\apps\worker.py", line 162, in run
    self.app.loader.init_worker()
  File "C:\Python27\lib\site-packages\celery\loaders\base.py", line 130, in init_worker
    self.import_default_modules()
  File "C:\Python27\lib\site-packages\djcelery\loaders.py", line 138, in import_default_modules
    self.autodiscover()
  File "C:\Python27\lib\site-packages\djcelery\loaders.py", line 141, in autodiscover
    self.task_modules.update(mod.__name__ for mod in autodiscover() or ())
  File "C:\Python27\lib\site-packages\djcelery\loaders.py", line 176, in autodiscover
    for app in settings.INSTALLED_APPS])
  File "C:\Python27\lib\site-packages\djcelery\loaders.py", line 195, in find_related_module
    return importlib.import_module('%s.%s' % (app, related_name))
  File "C:\Python27\lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "C:\sites\corecrm\people\tasks.py", line 15, in <module>
    from people.models import Customer, CustomerCsvFile, CustomerToTag, get_customer_from_csv_row
  File "C:\sites\corecrm\people\models.py", line 163, in <module>
    UserProfile._meta.get_field_by_name('username')[0]._max_length = 75
  File "C:\Python27\lib\site-packages\django\db\models\options.py", line 351, in get_field_by_name
    cache = self.init_name_map()
  File "C:\Python27\lib\site-packages\django\db\models\options.py", line 380, in init_name_map
    for f, model in self.get_all_related_m2m_objects_with_model():
  File "C:\Python27\lib\site-packages\django\db\models\options.py", line 469, in get_all_related_m2m_objects_with_model
    cache = self._fill_related_many_to_many_cache()
  File "C:\Python27\lib\site-packages\django\db\models\options.py", line 483, in _fill_related_many_to_many_cache
    for klass in get_models(only_installed=False):
  File "C:\Python27\lib\site-packages\django\db\models\loading.py", line 197, in get_models
    self._populate()
  File "C:\Python27\lib\site-packages\django\db\models\loading.py", line 75, in _populate
    self.load_app(app_name)
  File "C:\Python27\lib\site-packages\django\db\models\loading.py", line 96, in load_app
    models = import_module('.models', app_name)
  File "C:\Python27\lib\site-packages\django\utils\importlib.py", line 35, in import_module
    __import__(name)
  File "C:\sites\corecrm\booking\models.py", line 17, in <module>
    from people.models import Customer, UserProfile
ImportError: cannot import name Customer

为了弄清楚 booking/models.py 脚本在人们身上看到了什么,我在开头添加了以下内容:

import people
print 'path: %s' % people.__path__
for item in dir(people):
    print item

这给了我以下输出:

path: ['C:\\sites\\corecrm\\people']
__builtins__
__doc__
__file__
__name__
__package__
__path__
path: ['C:\\sites\\corecrm\\people']
__builtins__
__doc__
__file__
__name__
__package__
__path__

但是,当我运行 manage.py shell --settings=myproject.settings.dev_settings 时,我得到以下输出:

path: ['C:\\sites\\corecrm\\people']
__builtins__
__doc__
__file__
__name__
__package__
__path__
path: ['C:\\sites\\corecrm\\people']
__builtins__
__doc__
__file__
__name__
__package__
__path__
models

如您所见,models 模块位于 shell 命令的第二个列表的末尾(我已经确认除了 celery 之外的 manage.py 命令也是如此)。当我运行 celery 命令时,如何确保该模块在同一时间可用?

编辑:我现在还在 Ubuntu VM 上设置了这个项目,当我尝试运行 worker manage 命令时遇到了同样的错误。有任何想法吗?有人吗?

另一个编辑:我已将 booking/models.py 和 people/models.py 的代码粘贴到 http://pastebin.com/fTVVBtB4

【问题讨论】:

  • 你是否在 people/ 目录中缺少一个“init.py”(init 前后的双下划线)文件来告诉 Python 它是一个包?
  • 如果没有__init__.py,它根本就不存在
  • @Ricola3D:不,__init__.py 文件在那里,否则尝试运行 shell 管理命令(或任何其他命令)将不起作用。此外,人员应用程序是使用manage.py startapp people 创建的,它会自动将__init__.py 放入目录中
  • 循环导入可能吗?

标签: django celery django-celery


【解决方案1】:

我很确定这条线是你的问题:

File "C:\sites\corecrm\people\models.py", line 163, in <module>
    UserProfile._meta.get_field_by_name('username')[0]._max_length = 75

当您仍在忙于从 people.models 导入时,这条线(特别是 get_field_by_name)会强制 Django 评估模型并设置该模型与其相关模型之间的所有关系。这反过来又会强制在people.models 中导入Customer,而您仍在忙于导入该精确模型。这就是ImportError 的结果。

对于有效的解决方案,您需要发布您的 models.py。

为什么只有 celery 才会出现这个错误?如果没有更多信息,我不能肯定地说,但我最好的猜测是 Celery 处理导入的所有内容略有不同(Django 可能不会同时导入 CustomerCustomerCsvFileCustomerToTagget_customer_from_csv_row)并且这会暴露代码中的错误。

编辑/解决方案:
我会删除这一行:

UserProfile._meta.get_field_by_name('username')[0]._max_length = 75

并将其移至实例级别,进入__init__ 方法:

class UserProfile(AbstractUser):
    def __init__(self, *args, **kwargs):
        self._meta.get_field_by_name('username')[0]._max_length = 75
        super(UserProfile, self).__init__(*args, **kwargs)

如果问题的原因确实是我认为的那样,这将修复循环导入,同时提供相同的功能。如果 max_length 功能以某种方式被破坏(很可能是因为内部将 max_length 验证器添加到 CharField 并且 _max_length 更改得太晚了),我将覆盖 init 方法中的完整 username 字段:

class UserProfile(AbstractUser):
    def __init__(self, *args, **kwargs):
        super(UserProfile, self).__init__(*args, **kwargs)
        self._meta.get_field_by_name('username')[0] = models.CharField(max_length=75, etc.)

【讨论】:

  • 我已经发布了代码链接,而不是将其添加到这个问题中,因为它相当大
猜你喜欢
  • 1970-01-01
  • 2016-10-07
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2013-06-14
  • 2021-06-26
  • 2016-02-09
相关资源
最近更新 更多