如何在 django celery 中读取 .env 文件

问题描述

我使用了 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)。但是没有用。

芹菜.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,**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 219,in ensure_connection
    self.connect()
  File "/Users/junyoung/Dev/notification-drawer-api/venv/lib/python3.8/site-packages/django/utils/asyncio.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')

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...