我正在开发一个django应用程序,它必须处理用户上传的大型电子表格 - 所以我自然而然地转向芹菜和兔子。我成功设置了环境并且任务在后台成功完成,除了一个问题:我在db路由器类中使用几个环境变量(在我的apache vhost文件中定义并通过mod_wsgi传递给django)来确定要使用的数据库(即production vs staging vs dev):
class DbRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'auth':
return 'auth'
elif model._meta.app_label == 'admin':
return 'auth'
elif model._meta.app_label == 'contenttypes':
return 'auth'
else:
environment = environment = os.environ['BH_ENVIRONMENT_NAME']
if environment == "staging":
return 'staging'
if environment == "production":
return 'production'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'auth':
return 'auth'
elif model._meta.app_label == 'admin':
return 'auth'
elif model._meta.app_label == 'contenttypes':
return 'auth'
else:
###########################################
#This is where django raises the exception#
###########################################
environment = os.environ['BH_ENVIRONMENT_NAME']
if environment == "staging":
return 'staging'
if environment == "production":
return 'production'
def allow_migrate(self, db, app_label, model_name, **hints):
return True
在常规django线程中工作得很好;但是,当后台任务尝试使用db路由器时,我得到以下密钥错误(这似乎意味着工作线程无法使用os.environ
字典?):
[2018-02-16 14:23:01,516: ERROR/ForkPoolWorker-2] Task
exposures.tasks.process_exposure_file[27d7e651-e73e-49f1-bd20-8ab80b90d13a]
raised unexpected: KeyError('BH_ENVIRONMENT_NAME',)
Traceback (most recent call last):
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/celery/app/trace.py", line 374, in trace_task
R = retval = fun(*args, **kwargs)
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/celery/app/trace.py", line 629, in __protected_call__
return self.run(*args, **kwargs)
File "/home/bryan/PycharmProjects/BeachHouse/exposures/tasks.py", line 10,
in process_exposure_file
exposure = Exposure.objects.get(pk=exposure_id)
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/django/db/models/query.py", line 397, in get
num = len(clone)
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/django/db/models/query.py", line 254, in __len__
self._fetch_all()
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/django/db/models/query.py", line 1179, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/django/db/models/query.py", line 50, in __iter__
db = queryset.db
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/django/db/models/query.py", line 1109, in db
return self._db or router.db_for_read(self.model, **self._hints)
File "/var/www/BeachHouse/bhvenv/lib/python3.6/site-
packages/django/db/utils.py", line 258, in _route_db
chosen_db = method(model, **hints)
File "/home/bryan/PycharmProjects/BeachHouse/BeachHouse/db_routers.py", line
16, in db_for_read
environment = os.environ['BH_ENVIRONMENT_NAME']
File "/var/www/BeachHouse/bhvenv/lib/python3.6/os.py", line 669, in
__getitem__
raise KeyError(key) from None
KeyError: 'BH_ENVIRONMENT_NAME'
我尝试通过在settings.py文件中添加以下内容来解决此问题:
ENVIRONMENT_NAME = os.environ.get('BH_ENVIRONMENT_NAME')
并更新数据库路由器以使用settings.ENVIRONMENT_NAME
- 但是,当我在芹菜工作者终端打印出来时,它是空白的。我的celery.py文件如下(不确定是否相关?):
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ['DJANGO_SETTINGS_MODULE'] = 'BeachHouse.settings'
app = Celery('BeachHouse')
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('BeachHouse.settings', namespace='CELERY')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
所以问题是:如何将apache vhost变量传递给芹菜工作者 - 或者,如何将django设置传递给此工作线程(成功加载apache变量)?我想坚持使用apache虚拟主机方法来定义变量,如果可能的话,因为有许多设置从那里被拉出来。