Cron作业不加载virtualenv env var以使用django.setup()

时间:2017-04-01 12:55:40

标签: python django cron virtualenv crontab

好吧,我有一个像这样的项目结构:

my_project
   |-scripts
   |  |- my_script.py
   |
   |-django_project
      |- myApp
      |  |- models.py
      |  |- ...
      |- django_project
         |- settings.py
         |- ...

我在virtualenv中运行Django而在my_script.py我必须使用myApp.models

中的一些

所以,我就是这样做的:

my_script.py

#!/usr/bin/env python
import django
django.setup()

from myApp.models import foo

# do things

因为我在virtualenv中,为了让django.setup()正常工作,我设置了我的virtualenv($VIRTUAL_ENV/bin/postactivate):

export DJANGO_SETTINGS_MODULE = django_project.settings

我在路径中添加了django_project

$ workon my_virtualenv
$ python -c "import sys; print sys.path" 
['', '/my_project/django_project', ...]

这就是全部。

如果我激活我的virtualenv然后我运行my_script.py一切正常。

但如果我安排了类似的cron工作:

  <00> 00 00 * * * /.../.virtualenvs/my_virtualenv/bin/python /.../my_project/scripts/my_script.py>&gt; /.../test/test.log 2&gt;&amp; 1

我收到此错误:

  

django.core.exceptions.ImproperlyConfigured:请求的设置   LOGGING_CONFIG,但未配置设置。你必须要么   定义环境变量DJANGO_SETTINGS_MODULE或调用   在访问设置之前进行settings.configure()。

似乎my_virtualenv激活设置未正确加载。

为什么会发生这种情况,我该如何解决?

3 个答案:

答案 0 :(得分:1)

  

在你的python文件中试试这个:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project.settings")
import django
django.setup()

我建议您将my_script文件找到manage.py文件所在的项目根目录。

  

如果不起作用,请尝试这样:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project.django_project.settings")
import django
django.setup()

答案 1 :(得分:1)

我们使用一个小的shell脚本来激活virtualenv:

$ cat run-python.sh
#!/bin/bash

# put run-python.sh's directory on path (probably not needed, we call
# auxiliary scripts in the same directory)
myname="$0"
binprefix="$(dirname ${myname})"
export PATH=${binprefix}:${PATH}

VENV_DIR = '/path/to/venv/root'

# activate virtualenv
pushd ${VENV_DIR} > /dev/null
. bin/activate
popd > /dev/null

# set DJANGO_SETTINGS_MODULE
if [ "x$DJANGO_SETTINGS_MODULE" == "x" ]; then
  export DJANGO_SETTINGS_MODULE="default.settings"
else
  export DJANGO_SETTINGS_MODULE
fi

exec python $@

并在crontab中使用它,如:

0/15 * * * *    DJANGO_SETTINGS_MODULE=myapp.settings run-python.sh /path/to/python/script.py

答案 2 :(得分:0)

问题在于cron不是交互式外壳,因此您的.bash_profile和.bashrc都不是它的来源。

因此,您不会获得脚本virtualenvwrapper.sh的源代码,该脚本定义了workon命令以及挂钩的工作方式。

要解决这个问题,您可以直接在crontab中定义所需的变量集

WORKON_HOME= the same as in your .bash_profile
PROJECT_HOME= the same as in your .bash_profile
VIRTUALENVWRAPPER_SCRIPT= the same as the value of the variable VIRTUALENVWRAPPER_SCRIPT in interactive shell (usually /usr/local/bin/virtualenvwrapper.sh)

然后添加

source ${VIRTUALENVWRAPPER_SCRIPT}

在您计划的所有脚本的开头(如果您希望它们使用virtualenvwrapper)