Python----使用apscheduler模块设置定时任务

【原文链接】

一、安装

pip install apscheduler

二、ApScheduler 简介

1 APScheduler的组件

  • triggers:触发器
    triggers包含任务执行的调度逻辑,决定任务按照什么逻辑进行定时执行

  • job stores;任务存储器
    存储了调度任务

  • executors:执行器
    用例执行任务的,包含线程池以及进程池等的创建和调用等等

  • schedulers:调度器
    属于控制面,将其他几个方面组织起来的作用、

2 调度器的种类

调度器有以下几种常见类型,其中最常用的BackgroundScheduler,即非阻塞式,因为在一般情况下,定时任务都会在放到web服务中,如果使用阻塞式,则无法启动web服务,而使用非阻塞式,则将定时任务设定后,就不管了,继续执行后面的web服务,只要web服务在运行,定时任务就是一直有效的

  • BlockingScheduler: 阻塞式

  • BackgroundScheduler: 非阻塞式(后台运行)

  • AsyncIOScheduler: 当使用asyncio模块时使用

  • GeventScheduler: 当使用gevent模块时使用

  • TornadoScheduler: 构建Tornado应用时使用

  • TwistedScheduler: 构建Twisted应用时使用

  • QtScheduler: 构建Qt应用时使用

3 内置的触发器类型

  • date: 在某个时间点执行一次时使用

  • interval: 固定的时间间隔循环执行时使用

  • cron: 在一天中特定的时间点执行时使用

  • calendarinterval: 当想在在一天中特定时间点或以日历为基础的时间间隔内执行时使用

三、使用举例

这里jiu就以非阻塞式BackgroundScheduler调度器为例展开

1 使用date类型的触发器

如下,使用了三种设置日期和时间的方法

from apscheduler.schedulers.background import BackgroundScheduler
import time
from datetime import date
from datetime import datetime


def do_func(name,age):
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+" in do func : 姓名:"+name+" 年龄:"+str(age))

def main():
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    sched=BackgroundScheduler()

    # 通过date 设置指定日期执行
    sched.add_job(do_func,trigger="date",run_date=date(2022,5,25),args=("张三丰",100))

    # 通过datetime,设置指定日期额指定时刻执行
    sched.add_job(do_func, trigger="date", run_date=datetime(2022, 5, 25,14,0,10), args=("张三丰", 100))

    # 直接使用文本的方式指定日期和时刻表
    sched.add_job(do_func, trigger="date", run_date="2022-05-25 14:0:20", args=("张三丰", 100))

    sched.start()

if __name__=="__main__":
    main()
    while True:
        print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        time.sleep(1)

执行结果如下,可以发现,第一个通过date指定日期的默认是0点执行,显然时间已经过了,不会执行,第二和第三个则在规定的时间点执行了,这里还需要注意的是,通过打印可以看出,main函数执行完成后,已经开始执行main函数下面的while循环打印语句了,而在执行循环的过程中,定时任务仍然生效,这就是非阻塞式调度器的原理,如果是阻塞式,则在此代码中,会一直卡在main函数中,main下面额while循环语句是不会执行的,因此在实际使用中,非阻塞式应用的是非常多的

2022-05-25 14:00:02
2022-05-25 14:00:02
C:\Users\hitre\.virtualenvs\zentaolinkgitlab-QCS5yxD9\lib\site-packages\apscheduler\util.py:436: PytzUsageWarning: The localize method is no longer necessary, as this time zone supports the fold attribute (PEP 495). For more details on migrating to a PEP 495-compliant implementation, see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
  return tzinfo.localize(dt)
Run time of job "do_func (trigger: date[2022-05-25 00:00:00 CST], next run at: 2022-05-25 00:00:00 CST)" was missed by 14:00:02.088260
2022-05-25 14:00:03
2022-05-25 14:00:04
2022-05-25 14:00:05
2022-05-25 14:00:06
2022-05-25 14:00:07
2022-05-25 14:00:08
2022-05-25 14:00:09
2022-05-25 14:00:10 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:00:10
2022-05-25 14:00:11
2022-05-25 14:00:12
2022-05-25 14:00:13
2022-05-25 14:00:14
2022-05-25 14:00:15
2022-05-25 14:00:16
2022-05-25 14:00:17
2022-05-25 14:00:18
2022-05-25 14:00:19
2022-05-25 14:00:20 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:00:20
2022-05-25 14:00:21
2022-05-25 14:00:22

2 使用interval类型的触发器

如下代码演示了时间间隔循环执行的使用例子

from apscheduler.schedulers.background import BackgroundScheduler
import time
from datetime import date
from datetime import datetime


def do_func(name,age):
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+" in do func : 姓名:"+name+" 年龄:"+str(age))

def main():
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    sched=BackgroundScheduler()

    # 每3秒执行一次
    sched.add_job(do_func,trigger="interval",args=("张三丰",100),seconds=3)
    # 每3分钟执行一次
    sched.add_job(do_func, trigger="interval", args=("张三丰", 100), minutes=3)
    # 每3小时执行一次
    sched.add_job(do_func, trigger="interval", args=("张三丰", 100), hours=3)
    # 每3天执行一次
    sched.add_job(do_func, trigger="interval", args=("张三丰", 100), days=3)
    # 每3周执行一次
    sched.add_job(do_func, trigger="interval", args=("张三丰", 100), weeks=3)

    sched.start()

if __name__=="__main__":
    main()
    while True:
        print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        time.sleep(1)

上面的代码中因为时间跨度比较大,这里只演示妹3秒执行一次的代码
代码如下:

from apscheduler.schedulers.background import BackgroundScheduler
import time
from datetime import date
from datetime import datetime


def do_func(name,age):
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+" in do func : 姓名:"+name+" 年龄:"+str(age))

def main():
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    sched=BackgroundScheduler()

    # 每3秒执行一次
    sched.add_job(do_func,trigger="interval",args=("张三丰",100),seconds=3)

    sched.start()

if __name__=="__main__":
    main()
    while True:
        print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        time.sleep(1)

执行结果如下:

2022-05-25 14:14:04
2022-05-25 14:14:04
2022-05-25 14:14:05
2022-05-25 14:14:06
2022-05-25 14:14:07 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:14:07
2022-05-25 14:14:08
2022-05-25 14:14:09
2022-05-25 14:14:10 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:14:10
2022-05-25 14:14:11
2022-05-25 14:14:12
2022-05-25 14:14:13 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:14:13

3 使用cron类型的触发器

cron的触发器有点类似linux上crontab定时器的使用,代码如下:

from apscheduler.schedulers.background import BackgroundScheduler
import time
from datetime import date
from datetime import datetime


def do_func(name,age):
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+" in do func : 姓名:"+name+" 年龄:"+str(age))

def main():
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    sched=BackgroundScheduler()

    # 任务会在6月、7月、8月、11月和12月的第三个周五,00:00、01:00、02:00和03:00触发
    sched.add_job(do_func,trigger="cron",month='6-8,11-12', day='3rd fri', hour='0-3',args=("张三丰",100))

    sched.start()

if __name__=="__main__":
    main()
    while True:
        print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        time.sleep(1)

这里需要注意的是,可以省略不需要的字段。当省略时间参数时,在显式指定参数之前的参数会被设定为*,之后的参数会被设定为最小值,week 和day_of_week的最小值为*

day=1, minute=20
等同于
year='*', month='*', day=1, week='*', day_of_week='*', hour='*', minute=20, second=0

此外,也可以直接使用crontab表达式,如下:

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
import time
from datetime import date
from datetime import datetime


def do_func(name,age):
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+" in do func : 姓名:"+name+" 年龄:"+str(age))

def main():
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    sched=BackgroundScheduler()

    # 任务会在6月、7月、8月、11月和12月的第三个周五,00:00、01:00、02:00和03:00触发
    sched.add_job(do_func,trigger=CronTrigger.from_crontab('48 10 1-15 sep-nov *'),args=("张三丰",100))

    sched.start()

if __name__=="__main__":
    main()
    while True:
        print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        time.sleep(1)

四、定时器使用装饰器的方法

以间隔时间循环执行的代码为例,如下为未使用装饰器的方式

from apscheduler.schedulers.background import BackgroundScheduler
import time
from datetime import date
from datetime import datetime


def do_func(name,age):
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+" in do func : 姓名:"+name+" 年龄:"+str(age))

def main():
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    sched=BackgroundScheduler()

    # 每3秒执行一次
    sched.add_job(do_func,trigger="interval",args=("张三丰",100),seconds=3)

    sched.start()

if __name__=="__main__":
    main()
    while True:
        print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        time.sleep(1)

修改为使用装饰器的方式如下:

from apscheduler.schedulers.background import BackgroundScheduler
import time

sched=BackgroundScheduler()

@sched.scheduled_job(trigger="interval",args=("张三丰",100),seconds=3)
def do_func(name,age):
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+" in do func : 姓名:"+name+" 年龄:"+str(age))

if __name__=="__main__":
    sched.start()
    while True:
        print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        time.sleep(1)

执行结果如下:

2022-05-25 14:34:10
2022-05-25 14:34:11
2022-05-25 14:34:12
2022-05-25 14:34:13 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:34:13
2022-05-25 14:34:14
2022-05-25 14:34:15
2022-05-25 14:34:16 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:34:16
2022-05-25 14:34:17
2022-05-25 14:34:18
2022-05-25 14:34:19 in do func : 姓名:张三丰 年龄:100
2022-05-25 14:34:19
2022-05-25 14:34:20
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 可以使用Flask-APScheduler在MongoDB中实现定时任务,只需要在Flask应用中定义一个定时任务,并将其配置为在MongoDB中运行。具体代码如下:from flask_apscheduler import APSchedulerscheduler = APScheduler()# Configure the scheduler to use MongoDB as its job store scheduler.add_jobstore('mongodb', host='localhost', database='your_database_name')@scheduler.task('interval', id='do_job_1', seconds=30) def job_1(): print("Job 1 executed")@scheduler.task('cron', id='do_job_2', day_of_week='mon-sun', hour='12', minute='30') def job_2(): print("Job 2 executed")# Start the scheduler scheduler.start() ### 回答2: 要使用Flask-APScheduler实现数据库MongoDB定时任务,首先需要安装Flask-APScheduler和pymongo库。在Flask应用程序中,可以使用以下代码实现: 1. 首先,在app.py文件中导入所需的模块和库: ```python from flask import Flask from flask_apscheduler import APScheduler from pymongo import MongoClient ``` 2. 创建Flask应用程序实例: ```python app = Flask(__name__) ``` 3. 配置MongoDB连接并创建MongoDB客户端: ```python app.config['MONGO_URI'] = 'mongodb://localhost:27017/db_name' mongo_client = MongoClient(app.config['MONGO_URI']) ``` 请注意,`db_name`应替换为你的实际数据库名称,`localhost:27017`应替换为你的MongoDB服务器地址和端口。 4. 初始化APScheduler实例并配置任务存储: ```python scheduler = APScheduler() scheduler.init_app(app) scheduler.start() ``` 5. 创建一个定时任务函数,该函数将执行需要定时执行的操作。这里以向MongoDB数据库中插入一条记录为例: ```python def insert_data(): db = mongo_client.db_name collection = db.collection_name data = {'name': 'John', 'age': 30} collection.insert_one(data) ``` 请注意,`db_name`和`collection_name`应替换为你的实际数据库和集合名称。 6. 创建一个定时任务,并将其添加到APScheduler中: ```python scheduler.add_job(func=insert_data, trigger='interval', seconds=60) ``` 这将每隔60秒执行一次`insert_data`函数。 7. 最后,在Flask应用程序的入口处,启动Flask应用程序: ```python if __name__ == '__main__': app.run() ``` 以上代码片段演示了如何使用Flask-APScheduler和pymongo库实现数据库MongoDB定时任务的基本步骤。根据实际需求,你可以根据需要调整设置和任务函数。 ### 回答3: 要使用Flask-APScheduler实现MongoDB数据库的定时任务,需要先安装Flask和Flask-APScheduler库,并且确保MongoDB数据库已经正确安装和配置。 首先,在Flask应用中导入所需要的库和模块: ```python from flask import Flask from flask_apscheduler import APScheduler from pymongo import MongoClient ``` 然后,创建Flask应用和APScheduler实例并配置MongoDB数据库的连接: ```python app = Flask(__name__) scheduler = APScheduler() scheduler.init_app(app) # 配置MongoDB数据库连接 client = MongoClient('mongodb://localhost:27017/') # 替换为实际的MongoDB连接地址 db = client['mydatabase'] # 替换为实际的数据库名称 ``` 接下来,创建一个定时任务函数,该函数在特定时间间隔内会被调度执行,并且可以在函数中访问MongoDB数据库: ```python @scheduler.task('interval', id='my_job', minutes=30) def my_task(): collection = db['mycollection'] # 替换为实际的集合名称 # 在此处添加需要执行的MongoDB操作,例如插入、更新、删除等 # 例如:collection.insert_one({"name": "example"}) ``` 最后,启动定时任务调度器和Flask应用: ```python @app.route('/') def index(): return 'Flask-APScheduler MongoDB Demo' if __name__ == '__main__': scheduler.start() app.run() ``` 启动应用后,定时任务会按照预定的时间间隔执行,并且可以在`my_task()`函数中进行MongoDB的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

redrose2100

您的鼓励是我最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值