Celery Worker不从Django App继承设置

时间:2018-02-16 15:25:35

标签: python django celery

我正在开发一个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虚拟主机方法来定义变量,如果可能的话,因为有许多设置从那里被拉出来。

0 个答案:

没有答案