记录了在Django 中设置定时任务的过程。
需求
检查药品管理系统的数据库中有无过期药品。药品保质期和生产日期在两张不同表上,一个药品保质期对应多个生产日期,生产日期加保质期相加得到结果。
解决
Django 框架有一个 django-crontab 库也可以定时任务,但由于它是通过运行Linux 自带的cron 命令实现的,所以在Windows 系统上不能使用,所以最终选择了apscheduler实现
- 首先
pip install apschedule下载apscheduler模块,再pip install django-apscheduler,后者是保障定时任务在Django 项目中运行的库,包括注册、新建定时任务数据库等功能 - 在
setting.py的INSTALLED_APP中加入django-apschedule; - 使用
manage.py迁移数据库,会生成两个表django_apscheduler_djangojob和django_apscheduler_djangojobexecution用于存放定时器; - 在一个view 中写定时任务代码,这样只要运行程序,定时器就会被唤醒
- 初始化一个
apscheduler.schedulers.background.BackgroundScheduler()实例,这是后台的定时器; - 在要实现的任务函数上使用装饰器
@register_job进行设置,刚刚初始化的定时器作为第一个参数传入,除此之外可以传入:cron选择cron风格,传入周、时、分、秒定时运行;interval选择interval,传入时、分、秒,每间隔这么久运行
- 要实现的功能放在任务函数中
- 使用
register_event()将定时器注册,监控任务; - 最后定时器
start()开始运行。
代码
1 | from apscheduler.schedulers.background import BackgroundScheduler |
两张表的结构
django_apscheduler_djangojob
+———–+—————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———–+—————+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| status | varchar(50) | NO | | NULL | |
| run_time | datetime(6) | NO | MUL | NULL | |
| duration | decimal(15,2) | YES | | NULL | |
| started | decimal(15,2) | YES | | NULL | |
| finished | decimal(15,2) | YES | | NULL | |
| exception | varchar(1000) | YES | | NULL | |
| traceback | longtext | YES | | NULL | |
| job_id | int(11) | NO | MUL | NULL | |
+———–+—————+——+—–+———+—————-+
django_apscheduler_djangojobexecution
+—————+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+—————+————–+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | UNI | NULL | |
| next_run_time | datetime(6) | YES | MUL | NULL | |
| job_state | longblob | NO | | NULL | |
+—————+————–+——+—–+———+—————-+