Python Flask_APScheduler定时任务的正确(最佳)使用

描述 

APScheduler基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能。最近使用Flask框架使用Flask_APScheduler来做定时任务,在使用过程当中也遇到很多问题,例如在定时任务调用的方法中需要用到flask的app.app_context()时,需要使用current_app记录日志时,例如:current_app.logger.info("my_job已执行"),定时任务中使用current_app对象会报错,查看了很多资料,大部分资料都是说没有app就创建一个,这样确实也能解决,但是我总感觉这种解决是有问题的,拿.Net Core来说,使用Quartz.NET定时任务时,定时任务依赖于一个Host(主机)对象,不需要重复创建Host对象,但是Flask的app对象使用过程中却需要重新create app,Quartz.NET也是基于Quartz的定时任务框架,我使用过Quartz.NET,因此始终觉得Flask_APScheduler中create app使用是有问题,终于在过了一段时间后看到一位前辈使用Flask_APScheduler的一篇文章后,瞬间通达了,这个问题终于得到完美解决

 最佳使用Flask_APScheduler

 安装Flask_APScheduler

pip install Flask_APScheduler

1.项目结构图如下:

 

 2.Python 软件包utils下的__init__.py 初始化生成APScheduler对象

这里可以灵活处理,例如:也可以是common软件包下__init__.py里初始化APScheduler

 __init__.py的代码如下:

import atexit
import platform

from flask_apscheduler import APScheduler

# 初始化生成APScheduler对象
scheduler = APScheduler()


def init_scheduler(app):
    # 解决APScheduler定时任务重复执行的问题
    if platform.system() == 'Linux':
        # Linux 环境下
        fcntl = __import__("fcntl")
        f = open('scheduler.lock', 'wb')
        try:
            fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
            scheduler.init_app(app)
            scheduler.start()
        except Exception as e:
            app.logger.error(e)
            print(e)

        def unlock():
            fcntl.flock(f, fcntl.LOCK_UN)
            f.close()

        atexit.register(unlock)
    else:
        # Window 环境下
        msvcrt = __import__('msvcrt')
        f = open('scheduler.lock', 'wb')
        try:
            msvcrt.locking(f.fileno(), msvcrt.LK_NBLCK, 1)
            scheduler.init_app(app)
            scheduler.start()
        except Exception as e:
            pass

        def _unlock_file():
            try:
                f.seek(0)
                msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, 1)
            except Exception as e:
                pass
        atexit.register(_unlock_file)

3. config.py配置类代码

class Config:
    JOBS = [
        {
            'id': 'job1',
            'func': 'app:MyService.my_job',  # 注意这里的格式,app 是 Flask 应用对象的名称(app.py),: 后面是任务函数名
            'kwargs': {'job_name': 'job1'},
            'trigger': 'cron',
            'hour': 16,  # 16 点执行
            'minute': 58,  # 58 分执行
            'second': 0  # 0 秒执行
        },
        {
            'id': 'job2',
            'func': 'app:MyService.my_job',  # 注意这里的格式,app 是 Flask 应用对象的名称(app.py),: 后面是任务函数名
            'kwargs': {'job_name': 'job2'},
            'trigger': 'cron',
            'hour': 16,  # 16 点执行
            'minute': 58,  # 58 分执行
            'second': 3  # 3 秒执行
        },
        {
            'id': 'job3',
            'func': 'app:MyService.my_job',  # 注意这里的格式,app 是 Flask 应用对象的名称(app.py),: 后面是任务函数名
            'kwargs': {'job_name': 'job3'},
            'trigger': 'cron',
            'hour': 16,  # 16 点执行
            'minute': 58,  # 58 分执行
            'second': 6  # 6 秒执行
        }
    ]
    # 开启API功能,这样才可以用api的方式去查看和修改定时任务
    SCHEDULER_API_ENABLED = True

4.app.py中代码如下 

from config.config import Config  # 导入Config类的配置
from utils import init_scheduler  # 导入init_scheduler方法
# 创建Flask应用
app = Flask(__name__)
app.config.from_object(Config)  # 读取Config类的配置
init_scheduler(app)  # init_scheduler方法

5. MyService类中的my_job的方法使用app上下文

from flask import current_app  # 导入flask的current_app(当前app)
from utils import scheduler  # 很关键的一步 导入utils.__init__.py 初始化后的scheduler对象

class MyService:

    @classmethod
    def my_job(cls, job_name):
        # # # 此方法在定时任务多的情况下,会有性能问题,少的情况没啥问题
        # app = create_app()
        # with app.app_context():
        #     current_app.logger.info("my_job已执行")
        # #     print(f"my_job,当前时间{datetime.now()}")
        # # 使用全局APP变量
        # get_app()
        # with APP.app_context():
        #     current_app.logger.info(f"{job_name}已执行")
        #     print(f"my_job,当前时间{datetime.now()}")

        with scheduler.app.app_context():   # 这个sheduler是带有app及其上下文的
            current_app.logger.info(f"{job_name}已执行")

不建议使用 创建一个app的方法

create app的链接:https://blog.csdn.net/weixin_41934979/article/details/140406152 

6.执行效果如下: 

 源代码地址:https://gitee.com/jxzcode_admin/flask-project.git

 7.总结

 使用的Python 软件包下的__init__.py文件中初始化生成scheduler对象,此对象项目启动后只生成一次,然后导入scheduler对象,在定时任务执行的方法使用: with scheduler.app.app_context(): 就可以 获取flask当前app上下文,不需要create app,个人觉得这才是真正正确使用Flask_APScheduler

 参考资料

https://blog.csdn.net/arnolan/article/details/84936075

https://www.jianshu.com/p/d5a46b2d2fd3

### 回答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数据库的定时任务,需要先安装FlaskFlask-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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值