Reputation: 8599
Well, I have a project structure like this one:
my_project
|-scripts
| |- my_script.py
|
|-django_project
|- myApp
| |- models.py
| |- ...
|- django_project
|- settings.py
|- ...
I run Django inside a virtualenv and in my_script.py
I have to use some of myApp.models
So, here is how I did:
my_script.py
:
#!/usr/bin/env python
import django
django.setup()
from myApp.models import foo
# do things
Since I am inside a virtualenv, to make django.setup()
work properly I set in my virtualenv ($VIRTUAL_ENV/bin/postactivate
):
export DJANGO_SETTINGS_MODULE = django_project.settings
and I added django_project
to the path:
$ workon my_virtualenv
$ python -c "import sys; print sys.path"
['', '/my_project/django_project', ...]
And that's all.
If I activate my virtualenv and then I run my_script.py
all works fine.
But If I schedule a similar cron
job:
00 00 * * * /.../.virtualenvs/my_virtualenv/bin/python /.../my_project/scripts/my_script.py >> /.../test/test.log 2>&1
I get this error:
django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
It seems like my_virtualenv
activation settings are not properly loaded.
Why does this happen, and how can I fix?
Upvotes: 0
Views: 943
Reputation: 61
The problem is that cron is not an interactive shell and thus nor your .bash_profile nor your .bashrc are sourced by it.
Thus you do not source the script virtualenvwrapper.sh which is the one that defines the workon command and how hooks works.
To work around this fact you can define directly into the crontab the set of variables you need, that are
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)
and then add
source ${VIRTUALENVWRAPPER_SCRIPT}
at the beginning of all the scripts you are scheduling (if you want them to use virtualenvwrapper)
Upvotes: 0
Reputation: 27351
We use a small shell script to activate the 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 $@
and use it in crontab like:
0/15 * * * * DJANGO_SETTINGS_MODULE=myapp.settings run-python.sh /path/to/python/script.py
Upvotes: 1
Reputation: 1727
try with this on your python file:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project.settings")
import django
django.setup()
and I suggest you to locate your my_script
file to your project root directory where the manage.py
file is.
If not working, try like this:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project.django_project.settings")
import django
django.setup()
Upvotes: 1