Django-Crontab
Linux/Unix 에서 스케줄러를 구현할 때 cron/crontab을 Django에서는 django-crontab 라이브러리를 이용하면 쉽게 구현가능 하다.
django-crontab은 실제 os상의 crontab에 등록하여 동작하도록 설계되어있다.
Install
pip install django-crontab
setup
INSTALLED_APPS = (
'django_crontab',
. . .
)
cronjob 추가
자신이 스케줄 작업을 등록하기 위한 함수를 만들어주면 된다.
myapp/cron.py
# myapp/cron.py
def my_scheduled_job():
pass
settings.py
CRONJOBS = [
('*/5 * * * *', 'myapp.cron.my_scheduled_job'),
]
설정형식
# 분 시 일 월 요일 명령
# └───────────────────────── 분(0 - 59)
crontab 명령어
- 작업 추가
python manage.py crontab add
- 작업 목록 보기
python manage.py crontab show
- 작업 삭제
python manage.py crontab remove
예제
# crontab add
ihyeon-aui-MacBook-Pro:bcb ihyeon-a$ python3 manage.py crontab add --settings=base.settings.local_settings
adding cronjob: (e3e3313b7386a853fa281ba94b4c93eb) -> ('* * * * *', 'schedule.cron.schedule_system_alarm')
# crontab show
ihyeon-aui-MacBook-Pro:bcb ihyeon-a$ python3 manage.py crontab show --settings=base.settings.local_settings
Currently active jobs in crontab:
e3e3313b7386a853fa281ba94b4c93eb -> ('* * * * *', 'schedule.cron.schedule_system_alarm')
# crontab remove
ihyeon-aui-MacBook-Pro:bcb ihyeon-a$ python3 manage.py crontab remove --settings=base.settings.local_settings
removing cronjob: (e3e3313b7386a853fa281ba94b4c93eb) -> ('* * * * *', 'schedule.cron.schedule_system_alarm')
환경 변수 추가
Django 프로젝트를 settings.py 파일을 base.py, dev.py, local_settings.py 로 나누어서 운영하는 경우가 있을 것이다. 이럴 때 프로젝트를 실행하기 위해서는 manage.py 파일을 이용해서 실행하기 때문에 --settings 옵션을 줘서 실행한다. (Pycharm 에서 실행할 경우에는 환경 변수를 추가하여 실행할 것이다.)
하지만, cron 은 프로젝가 실행하지 않아도 crontab 에 설정된 파일이 주기적으로 실행되는 것이므로 프로젝트 실행을 위한 --settings 옵션을 아무리 줘봤자 실행이 되지 않는다. django-crontab 사이트를 보면 위에 정리된 crontab 명령어 말고도 환경설정을 위한 값들이 있다.
CRONTAB_DJANGO_SETTINGS_MODULE
settings.py 파일 안에 (또는 base.py 파일 안에) 프로젝트의 settings 파일 경로를 적어주면 된다.
CRONTAB_DJANGO_SETTINGS_MODULE = 'my_app.settings.local_settings'
한글 문제 (utf-8)
cron에 넣은 python script가 제대로 동작하지 않을 때 원인은 script 에 error 가 있는 것이다.
제일 먼저 알아야 할 것은 "cron 은 shell 과 환경이 다르다." 이다. 즉 shell 환경에서는 잘 실행되는 script 코드가 cron 에 넣으면 실행이 안된다면 그 둘의 실행 환경이 다르기 때문일 가능성이 높다.
예제
def test_cron():
print(1)
msg = "한글 메시지"
print(msg)
예를 들어, 위의 test_cron() 함수가 cron 에 추가되어 있다고 해보자. shell 환경에서 test_cron() 함수를 실행하면 아마 숫자 1과 "한글 메시지"가 잘 출력되어 나올 것이다. 하지만 cron 을 돌리면 숫자 1만 출력되고 "한글 메시지"가 출력되지 않을 것이다.
이유는 shell 에서는 대부분의 환경이 default encoding 으로 ko_KR.UTF-8 으로 되어 있어서 잘 나온다.(echo $LANG 으로 확인 가능) 하지만, cron 에서는 shell 의 인코딩을 끌고 가는 것이 아니라 encoding error 를 내고 실행이 중단될 수 있다. 이를 피하기 위해서는 python 의 기본 입출력 인코딩이 utf8 이라는 것을 명시적으로 지정해줘야 한다.
해결 방법
아래와 같이 crontab -e 명령어를 통해 cron 파일을 열고 파일 상단에 'PYTHONIOENCODING=utf8 ' 을 작성해 준다.
$ crontab -e
PYTHONIOENCODING=utf8
* * * * * /usr/bin/python /Users/ihyeon-a/Desktop/test.py
'Python > Django' 카테고리의 다른 글
[Django] settings.py 분리하기 (0) | 2016.11.16 |
---|---|
[Django] Database Dynamic Access (0) | 2016.11.14 |
[Django] values() values_list() flat (0) | 2016.10.26 |
[Django] File upload (FileField, ImageField) (0) | 2016.10.19 |
[Django] uwsgi + nginx in ubuntu (0) | 2016.10.18 |
댓글