I have a django script that should be run at a specified time every day. I am trying to achieve this using crontab. The script is supposed to dump the database, archive it using gzip and upload it to bitbucket.
The following is the relevant part of my crontab file:
00 4 * * * root python /my_django_project_path/manage.py update_locations
47 16 * * * root python /my_django_project_path/manage.py database_bu
When I execute python /my_django_project_path/manage.py database_bu it works perfectly fine. However crontab either does not execute it or something happens along the way. Even weirder, the first crontab command (update_locations) is executed perfectly fine.
Reading this question, I have tried the following, without success:
Changing the command to:
47 16 * * * root (cd /my_django_project_path/ && python manage.py database_bu)
Changing the command to:
47 16 * * * root /usr/bin/python /my_django_project_path/manage.py database_bu
Adding the following to my script (even though the other one works fine without it):
#!/usr/bin/python
from django.core.management import setup_environ
import settings
setup_environ(settings)
Running everything through a script that exports the django project settings:
/my_django_project_path/cron_command_executor.sh:
export DJANGO_SETTINGS_MODULE=my_django_project.settings
python manage.py ${*}
The following in crontab:
47 16 * * * root ./my_django_project_path/cron_command_executor.sh database_bu
Changing the user to both my user and the Apache user (www-data).
I have a newline at the end of my crontab file.
UPDATE:
When doing sudo su, running the command manually no longer works. It gets stuck and doesn't do anything.
The output of tail -f /var/log/syslog is:
Mar 3 18:26:01 my-ip-address cron[726]: (system) RELOAD (/etc/crontab)
Mar 3 18:26:01 my-ip-address CRON[1184]: (root) CMD (python /my_django_project_path/manage.py database_bu)
UPDATE:
I am using the following .netrc file to prevent git asking for credentials:
machine bitbucket.org
login myusername
password mypassword
The actual code for the backup script is:
import subprocess
import sh
import datetime
import gzip
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
execute_backup()
FILE_NAME = 'some_file_name.sql'
ARCHIVE_NAME = 'some_archive_name.gz'
REPO_NAME = 'some_repo_name'
GIT_USER = 'some_git_username' # You'll need to change this in .netrc as well.
MYSQL_USER = 'some_mysql_user'
MYSQL_PASS = 'some_mysql_pass'
DATABASE_TO_DUMP = 'SomeDatabase' # You can use --all-databases but be careful with it! It will dump everything!.
def dump_dbs_to_gzip():
# Dump arguments.
args = [
'mysqldump', '-u', MYSQL_USER, '-p%s' % (MYSQL_PASS),
'--add-drop-database',
DATABASE_TO_DUMP,
]
# Dump to file.
dump_file = open(FILE_NAME, 'w')
mysqldump_process = subprocess.Popen(args, stdout=dump_file)
retcode = mysqldump_process.wait()
dump_file.close()
if retcode > 0:
print 'Back-up error'
# Compress.
sql_file = open(FILE_NAME, 'r')
gz_file = gzip.open(ARCHIVE_NAME, 'wb')
gz_file.writelines(sql_file)
gz_file.close()
sql_file.close()
# Delete the original file.
sh.rm('-f', FILE_NAME)
def clone_repo():
# Set the repository location.
repo_origin = 'https://%s@bitbucket.org/%s/%s.git' % (GIT_USER, GIT_USER, REPO_NAME)
# Clone the repository in the /tmp folder.
sh.cd('/tmp')
sh.rm('-rf', REPO_NAME)
sh.git.clone(repo_origin)
sh.cd(REPO_NAME)
def commit_and_push():
# Commit and push.
sh.git.add('.')
sh.git.commit(m=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
sh.git.push('origin', 'master')
sh.cd('..')
sh.rm('-rf', REPO_NAME)
def execute_backup():
clone_repo()
dump_dbs_to_gzip()
commit_and_push()
if __name__ == "__main__":
execute_backup()
UPDATE:
I managed to fix it using Chris Clark's suggestion of calling the script directly rather than through manage.py. However, I am still interested in what is causing this issue so the bounty is still available.
UPDATE [SOLVED]:
Adding the following line to /etc/environment and running it as my user account rather than root fixed it:
PWD=/my_django_project_path/helpers/management/commands
I still wonder why only my user can run it so if anyone has the solution to that, please contribute.