sqlalchemy db在apscheduler的函数调用中找不到应用程序

时间:2019-07-15 20:14:06

标签: flask sqlalchemy apscheduler

Sqlalchemy DB无法在apscheduler进行的函数调用内访问应用程序。失败,显示“未找到应用程序。可以在视图函数内部进行操作,也可以按“。”

我想知道如何处理预定函数内部的任何数据库查询?

我尝试了几件事。我试图将db作为参数传递给计划的函数,但它选择了。 我使用打印(db.get_ap())进行了检查,可以看到它可以在create_ssh_job()中找到该APP,但在sch_processCLIcommands()中却找不到。 两种功能都在同一个文件中。

from mytools.sendCommand_InvokeShell import processCLIcommands
from data.models import job_manager,Job,db
from flask_security import current_user


# THIS IS THE FUNCTION WHICH IS CALLED BY APSCHEDULER 
def sch_processCLIcommands(jobid,app_root_path,devices,commands):
        print(f"Running JobID: {jobid}")
        # outputfileurl,summary = processCLIcommands(app_root_path,devices,commands)
        print(f"updating JobID: {jobid}")

        # you try to call editjob using job_manager object. So you have to create a new object
        print("Accessing the APP: " ,db.get_app())

        job = db.session.query(Job).filter_by(id=jobid).first()  >>>>>> THIS IS WHERE IT FAILS
        print(type(job), job.get_job_as_dict())
        return True


# THIS FUNCTION ADDS THE sch_processCLIcommands TO THE JOBS.
def create_ssh_job(app,job_description,devices,commands,schedule):


    # Now create a job entry in the scheduler.
    if schedule['trigger'] == 'date':
            app.apscheduler.add_job(func=sch_processCLIcommands, trigger='date',
                                run_date=schedule['startdatetime'],
                                args=[app.root_path,devices,schedule], id = str("TEST") )



    return True

这是错误:

Traceback (most recent call last):
  File "C:\Python_Projects\quickAuto\env\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "C:\Python_Projects\quickAuto\mytools\scheduled_jobs.py", line 19, in sch_processCLIcommands
    editjob(jobid,outputfileurl)
  File "C:\Python_Projects\quickAuto\mytools\scheduled_jobs.py", line 11, in editjob
    job.editjob(jobid,outputfileurl)
  File "C:\Python_Projects\quickAuto\data\models.py", line 368, in editjob
    db.session.rollback()
  File "C:\Python_Projects\quickAuto\env\lib\site-packages\sqlalchemy\orm\scoping.py", line 153, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "C:\Python_Projects\quickAuto\env\lib\site-packages\sqlalchemy\util\_collections.py", line 1001, in __call__
    return self.registry.setdefault(key, self.createfunc())
  File "C:\Python_Projects\quickAuto\env\lib\site-packages\sqlalchemy\orm\session.py", line 2950, in __call__
    return self.class_(**local_kw)
  File "C:\Python_Projects\quickAuto\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 141, in __init__
    self.app = app = db.get_app()
  File "C:\Python_Projects\quickAuto\env\lib\site-packages\flask_sqlalchemy\__init__.py", line 912, in get_app
    'No application found. Either work inside a view function or push'
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.

2 个答案:

答案 0 :(得分:0)

我通过将应用程序导入到我的实用程序文件中解决了问题,然后执行db.app = app

from app import app


def sch_processCLIcommands(jobid,app_root_path,devices,commands):
        db.app = app

答案 1 :(得分:0)

如果要在apscheduler任务中使用Sqlalchemy DB,请使用with scheduler.app.app_context():
像这样:

    def sch_processCLIcommands(jobid,app_root_path,devices,commands):
        print(f"Running JobID: {jobid}")
        # outputfileurl,summary = processCLIcommands(app_root_path,devices,commands)
        print(f"updating JobID: {jobid}")

        # you try to call editjob using job_manager object. So you have to create a new object
        print("Accessing the APP: " ,db.get_app())
        # scheduler should start at  init
        with scheduler.app.app_context():
            job = db.session.query(Job).filter_by(id=jobid).first()  >>>>>> THIS IS WHERE IT FAILS
        print(type(job), job.get_job_as_dict())
        return True


初始化调度程序

scheduler = APScheduler()

# app is Flask object
def init_scheduler(app:Flask):
    scheduler.init_app(app)
    scheduler.start()