Django高级特性之django-apscheduler定时任务,给Django添加run,右键运行

今天搞了一天 终于搞出来了 ,后边改造的话,就可以把系统计划任务搞到Django里面,网上文章很乱,后边代码都是自己验证的 ,赶紧记录下来。

django-apscheduler
支持三种调度任务:固定时间间隔,固定时间点(日期),Crontab 命令。同时,它还支持异步执行、后台执行调度任务 配置简单、功能齐全、使用灵活、支持windows和linux,适合中小型项目。

基础组件

APScheduler 有四种组件,分别是:
调度器(scheduler),
作业存储(job store),
触发器(trigger),
执行器(executor)。

  • schedulers(调度器) 它是任务调度器,属于控制器角色。它配置作业存储器和执行器可以在调度器中完成,例如添加、修改和移除作业。
  • triggers(触发器) 描述调度任务被触发的条件。不过触发器完全是无状态的。
  • job stores(作业存储器)
    任务持久化仓库,默认保存任务在内存中,也可将任务保存都各种数据库中。
  • executors(执行器)
    负责处理作业的运行,它们通常通过在作业中提交指定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。

schedulers(调度器)
它提供 7 种调度器,能够满足我们各种场景的需要。例如:后台执行某个操作,异步执行操作等。调度器分别是:

  • BlockingScheduler : 调度器在当前进程的主线程中运行,也就是会阻塞当前线程。
  • BackgroundScheduler : 调度器在后台线程中运行,不会阻塞当前线程。(Django框架使用)
  • AsyncIOScheduler : 结合 asyncio 模块(一个异步框架)一起使用。
  • GeventScheduler : 程序中使用 gevent(高性能的Python并发框架)作为IO模型,和 GeventExecutor
    配合使用。
  • TornadoScheduler : 程序中使用 Tornado(一个web框架)的IO模型,用 ioloop.add_timeout
    完成定时唤醒。
  • TwistedScheduler : 配合 TwistedExecutor,用 reactor.callLater
    完成定时唤醒。scrapy爬虫框架
  • QtScheduler : 你的应用是一个 Qt 应用,需使用QTimer完成定时唤醒。

triggers(触发器)

  • date 触发器 作业任务只会执行一次。它表示特定的时间点触发。它的参数如下:
    run_date (datetime 或 str) 作业的运行日期或时间
    timezone (datetime.tzinfo 或 str) 指定时区

  • interval 触发器 固定时间间隔触发。interval 间隔调度,参数如下:
    weeks (int) 间隔几周
    days (int) 间隔几天
    hours (int) 间隔几小时
    minutes (int) 间隔几分钟
    seconds (int) 间隔多少秒
    start_date (datetime 或 str) 开始日期
    end_date (datetime 或 str) 结束日期
    timezone (datetime.tzinfo 或str) 时区

  • cron 触发器 在特定时间周期性地触发,和Linux crontab格式兼容。
    参数 说明
    year (int 或 str) 年,4位数字
    month (int 或 str) 月 (范围1-12)
    day (int 或 str) 日 (范围1-31
    week (int 或 str) 周 (范围1-53)
    day_of_week (int 或 str) 周内第几天或者星期几 (范围0-6 或者 mon,tue,wed,thu,fri,sat,sun)
    hour (int 或 str) 时 (范围0-23)
    minute (int 或 str) 分 (范围0-59)
    second (int 或 str) 秒 (范围0-59)
    start_date (datetime 或 str) 最早开始日期(包含)
    end_date (datetime 或 str) 最晚结束时间(包含)
    timezone (datetime.tzinfo 或str) 指定时区

表达式类型

表达式 参数类型 描述

  • 所有 通配符。例:minutes=*即每分钟触发
    */a 所有 可被a整除的通配符。
    a-b 所有 范围a-b触发
    a-b/c 所有 范围a-b,且可被c整除时触发
    xth y 日 第几个星期几触发。x为第几个,y为星期几
    last x 日 一个月中,最后个星期几触发
    last 日 一个月最后一天触发
    x,y,z 所有 组合表达式,可以组合确定值或上方的表达式

作业存储(job store)
有两种添加方法,其中一种是 add_job(), 另一种则是@register_job()修饰器来修饰函数。

这个两种办法的区别是:第一种方法返回一个 Job 的实例,可以用来改变或者移除 job。第二种方法只适用于应用运行期间不会改变的 job。

django-apscheduler框架还提供了很多操作定时任务的函数。比如:

删除任务
scheduler.remove_job(job_name)
暂停任务
scheduler.pause_job(job_name)
开启任务
scheduler.resume_job(job_name)
获取所有任务
scheduler.get_jobs()
修改任务
scheduler.modify_job(job_name)
注:修改任务只能修改参数,如果要修改执行时间的话,有3种方法
第一就把任务删了重新创建,
第二直接操作数据库,
第三用到下面重设任务。

重设任务
scheduler.reschedule_job(job_name)
scheduler.reschedule_job(job_id=“job1”, trigger=‘interval’, minutes=1)

执行器(executor)
执行调度任务的模块。最常用的 executor 是 ThreadPoolExecutor,存储路径是在Django数据库中

说了这么多 上个代码吧

安装

pip3 install django-apscheduler

配置

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_apscheduler',
]

把django_apscheduler弄进来,然后要做下迁移 。
测试发现,多个任务的话 ,sqlite3 存在数据库锁住的问题,因为sqlite3只能1个写入,不能多个写入。
Django高级特性之django-apscheduler定时任务,给Django添加run,右键运行_第1张图片
所以我就给改成MySQL了

DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # 配置连接数据库 ,导入pymysql类库
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'HOST': 'ip',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': 'password'
    }
}

改成MySQL还一个问题,要在项目的__init__.py里面加上

#import pymysql
#pymysql.install_as_MySQLdb()

不然 连接数据库又是问题,这样就可以迁移了
20220408更新
加上放服务器上不好使,还得安装mysqlclient
apt-get install libmariadbd-dev
pip3 install myqlclient

python manage.py migrate

代码业务逻辑

然后建议你新建一个应用,在新应用的视图(view)里就可以写定时任务的逻辑了

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.

import time
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_job, register_events

print('django-apscheduler')


def job2(name):
    # 具体要执行的代码
    print('{} 任务运行成功!{}'.format(name, time.strftime("%Y-%m-%d %H:%M:%S")))


def job3(name):
    print('{} 任务运行成功!{}'.format(name, time.strftime("%Y-%m-%d %H:%M:%S")))


# 实例化调度器
scheduler = BackgroundScheduler(timezone='Asia/Shanghai') # 这个地方要加上时间,不然他有时间的警告

# 调度器使用DjangoJobStore()
scheduler.add_jobstore(DjangoJobStore(), "default")


# 添加任务1
# 每隔5s执行这个任务,这个就是装饰器的玩法
@register_job(scheduler, "interval", seconds=5, args=['老K'], id='job1', replace_existing=True)

def job1(name):
    # 具体要执行的代码
    print('{} 任务运行成功!{}'.format(name, time.strftime("%Y-%m-%d %H:%M:%S")))

# 下面这就是add_job的方式 interval
scheduler.add_job(job2, "interval", seconds=10, args=['老Y'], id="job2", replace_existing=True)

# 下面这就是add_job的方式 crontab  16点 38分  40分执行
scheduler.add_job(job3, 'cron', hour='16', minute='38,40', args=['鬼人'], id='job3', replace_existing=True)

"""
20220408更新 
id可以不加,如果不加ID是这个应用view下的函数名字

replace_existing=True 这个东西不加的话,他会提示ID冲突了,我查了好多文章,把这答案找出来了 。
"""
# 监控任务
register_events(scheduler) # 这个event 这个会有已经被废弃的用法删除线,我不知道这个删除了 ,还会不会好用
# 调度器开始运行
scheduler.start()


def index(request):
    return HttpResponse('ok')

运行

这运行的时候,我一开始都是

python manager.py runserver

今天弄的时候 ,代码写的有问题了,然后这货都停不下来了 ,ctrl c都不好使
后来想了一招,给Django添加一个run 让他可以右键运行

在整个项目下面添加一个runner.py

import os

if __name__ == '__main__':
    os.system('python manage.py runserver')

右键就可以运行django项目了

你可能感兴趣的:(#,django,django)