如何在 Django 芹菜中读取 .env 文件

How to read .env file in django celery

我使用了 celery (5.0.5)、django (3.1.1)、django-dotenv

项目结构

project
ㅣ-api
ㅣ----task.py
ㅣ----...
ㅣ-config
ㅣ----settings.py
ㅣ----celery.py
ㅣ----...
manage.py
.env

键入 celry -A config worker -l INFO 导致错误

我似乎无法读取 .env 文件

因为它在 db.splite3 中工作正常

我尝试在 celery.py 中添加代码 dotenv.read_dotenv(env_file)。但是没用。

celery.py

import os

import dotenv
from celery import Celery

# set the default Django settings module for the 'celery' program.
from config.settings import BASE_DIR

# I tried this but it didn't work
# env_file = os.path.join(BASE_DIR, '.env')
# dotenv.read_dotenv(env_file)

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery('config')

app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

app.conf.beat_schedule = {
    'add-every-30-seconds': {
        'task': 'api.tasks.show',
        'schedule': 10.0,
    },
}
app.conf.timezone = 'UTC'

但是在终端里设置环境变量效果很好,就是每次都要输入

export DB_PASSWORD=..
export DB_USER=..
..

.env

DB_PASSWORD='pw'
DB_NAME='db_name'
DB_USER='root'
DB_HOST='127.0.0.1'
DB_PORT='3306'

我错过了什么?

> celery -A config worker -l INFO
Traceback (most recent call last):
  File "/Users/junyoung/Dev/notification-drawer-api/venv/bin/celery", line 10, in <module>
    sys.exit(main())
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/__main__.py", line 15, in main
    sys.exit(_main())
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/bin/celery.py", line 213, in main
    return celery(auto_envvar_prefix="CELERY")
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/bin/base.py", line 132, in caller
    return f(ctx, *args, **kwargs)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/bin/worker.py", line 320, in worker
    worker = app.Worker(
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/worker/worker.py", line 94, in __init__
    self.app.loader.init_worker()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/loaders/base.py", line 111, in init_worker
    self.import_default_modules()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/loaders/base.py", line 105, in import_default_modules
    raise response
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/utils/dispatch/signal.py", line 276, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/fixups/django.py", line 82, in on_import_modules
    self.worker_fixup.validate_models()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/celery/fixups/django.py", line 121, in validate_models
    run_checks()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/core/checks/registry.py", line 70, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django_mysql/checks.py", line 14, in check_variables
    with connection.temporary_connection() as cursor:
  File "/Users/junyoung/opt/anaconda3/lib/python3.8/contextlib.py", line 113, in __enter__
    return next(self.gen)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 603, in temporary_connection
    with self.cursor() as cursor:
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 259, in cursor
    return self._cursor()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    self.ensure_connection()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 199, in connect
    conn_params = self.get_connection_params()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 207, in get_connection_params
    if settings_dict['HOST'].startswith('/'):
AttributeError: 'NoneType' object has no attribute 'startswith'

settings.py

DATABASES = {
    # Not Worked! :(
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get("DB_NAME"),
        'USER': os.environ.get("DB_USER"),
        'PASSWORD': os.environ.get("DB_PASSWORD"),
        'HOST': os.environ.get("DB_HOST"),
        'PORT': os.environ.get("DB_PORT"),
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    },
    #  Worked! :)
    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': BASE_DIR / 'db.sqlite3',
    # }
}

我解决了这个问题

我将其添加到 settings.py 而不是 celery.py。 dotenv.read_dotenv ('./.env')

希望对遇到同样问题的人有所帮助