본문 바로가기
Python/Django

[Django] django-crontab

by 혀나Lee 2016. 10. 28.

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 - 7): 0에서 6까지 일요일에서 토요일, 혹은 이름을 사용. 7도 일요일임 # │ │ │ └────────── 월(1 - 12) # │ │ └─────────────── 일(1 - 31) # │ └──────────────────── 시(0 - 23)

# └───────────────────────── 분(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

댓글