我在 docker 经营Django 和Celery .它运行正常,但在我重启Docker后,由于导入名称错误,Celery 无法启动.

错误如下:

v_web            | Traceback (most recent call last):
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 354, in run_from_argv
v_web            |     self.execute(*args, **cmd_options)
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 393, in execute
v_web            |     self.check()
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 423, in check
v_web            |     databases=databases,
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/core/checks/registry.py", line 76, in run_checks
v_web            |     new_errors = check(app_configs=app_configs, databases=databases)
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/core/checks/urls.py", line 100, in check_url_settings
v_web            |     value = getattr(settings, name)
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 82, in __getattr__
v_web            |     self._setup(name)
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 69, in _setup
v_web            |     self._wrapped = Settings(settings_module)
v_web            |   File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 170, in __init__
v_web            |     mod = importlib.import_module(self.SETTINGS_MODULE)
v_web            |   File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
v_web            |     return _bootstrap._gcd_import(name[level:], package, level)
v_web            |   File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
v_web            |   File "<frozen importlib._bootstrap>", line 983, in _find_and_load
v_web            |   File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
v_web            |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
v_web            |   File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
v_web            |   File "<frozen importlib._bootstrap>", line 983, in _find_and_load
v_web            |   File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
v_web            |   File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
v_web            |   File "<frozen importlib._bootstrap_external>", line 728, in exec_module
v_web            |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
v_web            |   File "/app/notification/__init__.py", line 1, in <module>
v_web            |     from .celery import app as celery_app
v_web            |   File "/app/notification/celery.py", line 2, in <module>
v_web            |     from celery import Celery
v_web            | ImportError: cannot import name 'Celery' from 'celery' (/usr/local/lib/python3.7/site-packages/celery/__init__.py)

以下是我的项目 struct :

notifications
   notification
      __init__.py
      celery.py

下面是我的init.py文件:

from .celery import app as celery_app
__all__ = ("celery_app",)

这是我的celery.py:

import os
from celery import Celery

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "notification.settings")

app = Celery("notification")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()

这是我的 docker 档案:

version: "3.9"
   
services:

  redis:
    container_name: v_redis
    image: redis:alpine
    restart: always

  db:
    container_name: v_db
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    env_file:
      - ./production.env
    restart: always

  web:
    container_name: v_web
    build: .
    command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --no-input && gunicorn notification.wsgi:application --limit-request-line 0 --workers=4 --threads=4 --worker-class=gthread --bind 0.0.0.0:8000"
    env_file:
      - ./production.env
    volumes:
      - .:/app
      - ./staticfiles:/staticfiles
    expose:
      - 8000
    depends_on:
      - db
      - redis
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/"]
      interval: 30s
      timeout: 10s
      retries: 5

  celery:
    container_name: v_celery
    build: .
    command: celery -A notification worker -l info --concurrency 4
    env_file:
      - ./production.env
    # volumes:
    #   - ./redis/:/usr/src/app/
    depends_on:
      web:
        condition: service_healthy
      redis:
        condition: service_started
    restart: always


  celery-beat:
    container_name: v_celery_beat
    build: .
    command: celery -A notification beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler
    env_file:
      - ./production.env
    # volumes:
    #   - ./redis/:/usr/src/app/
    depends_on:
      - redis
    restart: always

  flower:
    container_name: v_celery_flower
    image: mher/flower
    command: celery flower
    environment:
      - CELERY_BROKER_URL=redis://redis:6379/0
      - FLOWER_PORT=5555
    ports:
      - 5555:5555
    depends_on:
      - redis
    restart: always

  nginx:
    container_name: v_nginx
    build: ./nginx
    volumes:
      - ./staticfiles:/staticfiles
      # - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 80:80
      - 443:443
    depends_on:
      - web
    restart: always

我的文档文件:

# syntax=docker/dockerfile:1
FROM python:3.7
WORKDIR /app
COPY . /app/
RUN pip install -r requirements.txt

我的要求.txt:

Django>=3.0,<4.0
gunicorn==20.1.0
psycopg2-binary>=2.8
django-crispy-forms
django-celery-beat
django-select2
django-redis
slack_sdk
PyMuPDF
Pillow
google-api-python-client
google-auth-oauthlib
oauth2client
pandas
celery==5.1.2
redis==3.5.3
sqlalchemy
sshtunnel
matplotlib
boto3

我不知道为什么重建Dockerfile后会失败.请帮帮忙.谢谢.

推荐答案

此错误为bug,只有python 3.7(与您使用的版本相同)才会出现此错误,因为importlib-metadata的最新版本.

刚刚降级importlib-metadata<5.0:pip install importlib-metadata==4.13.0

Django相关问答推荐

在Django URL模式中使用多个空路由可以吗?

如何在Django模型mixin字段定义中引用模型名称?

批量删除多对多条目?

Django www.example.com从常量列表中删除值

如何在对接合成时创建两个Postgres数据库?

在Django管理中仅显示外键的特定值

在模板中自动添加变量

在 Django 中重组多对多字段

根据当前对象中的多对多字段过滤对象

如何将 ManyToManyField 与另一个 ManyToManyField 进行比较

何时在 django 中使用 pre_save、save、post_save?

Django REST Framework - 将额外参数传递给操作

一个简单的Django和CSS示例

Django聚合:仅求和返回值?

django 复数模板

Django中的自定义排序

Django 模型:delete() 未触发

在 Django 中的字段中添加额外的约束

Django Rest Framework 序列化程序中的循环依赖

显式 cursor.close() 的必要性