简体   繁体   English

Flask-Apscheduler及其应用上下文

[英]Flask-Apscheduler and the Application Context

Brief: I am trying to use flask-apscheduler to regularly create and upload csv backups of certain data from a MySQL database using my models (and sqlalchemy as my ORM) to S3. 简介:我正在尝试使用flask-apscheduler定期使用我的模型(以及sqlalchemy作为我的ORM)从MySQL数据库中创建某些数据的csv备份并将其上传到S3。 In the past, I wrote a seperate script and ran through a cron job. 过去,我编写了单独的脚本并执行了cron作业。 However, I wanted to experiment with flask-apscheduler and now I need to figure out why it won't work! 但是,我想试验flask-apscheduler,现在我需要弄清楚为什么它不起作用!

Stats: 统计:

Flask==0.10.1
Flask-APScheduler==1.6.0
Flask-SQLAlchemy==2.0
</pre>

Structure of App:
<pre>
/app
  /main
  /auth
  __init__.py
  models.py
  utilities.py

config.py

init .py

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from config import config
from flask_apscheduler import APScheduler
import logging

login_manager                       = LoginManager()
login_manager.session_protection    = 'strong'
login_manager.login_view            = 'auth.login'

moment      = Moment()
db          = SQLAlchemy()
sched       = APScheduler()

def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])

    config[config_name].init_app(app)
    db.init_app(app)
    login_manager.init_app(app)
    sched.init_app(app)

    sched.start()

    # Set up logging
    if not app.debug:
        app.logger.addHandler(logging.StreamHandler())
        app.logger.setLevel(logging.DEBUG)

        logger = logging.getLogger('flask_logger')
    else:
        logging.basicConfig()

    from .main import main as main_blueprint
    from .auth import auth as auth_blueprint

    app.register_blueprint(main_blueprint)
    app.register_blueprint(auth_blueprint, url_prefix = '/auth')

    return app

if __name__ == "__main__":
    app = create_app('development')

config.py

...
JOBS = [
        {
            'id': 'job1',
            'func': 'app.utilities:backup_data_to_s3',
            'kwargs': {'bucket': AWS_BUCKET},
            'trigger': {'type': 'cron', 'hour': '0'}
        }
    ]
...

utilities.py

from datetime import date, datetime, timedelta
import sendgrid
from flask import current_app, g
import boto3
from app.models import *

def backup_data_to_s3(**kwargs):
    """
    length_of_time: in number of days
    start: datetime.date object
    end: datetime.date object
    """
    t0 = date.today()

    bucket_name = kwargs.pop('bucket')
    start       = kwargs.pop('start', t0 - timedelta(days = 1))
    end         = kwargs.pop('end', t0)

    # Get the number of days
    dt      = (end - start).days

    s3          = boto3.resource('s3')
    bucket      = s3.Bucket(bucket_name)
    updated     = 0

    ...
    return

The traceback for the primary error that I receive is: 我收到的主要错误的追溯是:

Traceback (most recent call last):
  File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/apscheduler/executors/base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "/Users/dh/Documents/GitHub/web-tata/web-tata/app/utilities.py", line 65, in backup_data_to_s3
    print (g)
  File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/werkzeug/local.py", line 357, in <lambda>
    __str__ = lambda x: str(x._get_current_object())

  File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
    return self.__local()
  File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/flask/globals.py", line 27, in _lookup_app_object
    raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context

It's pretty obvious that there is just something going on with how flask handles the application context, but I'm not quite aware of exactly how it works...Any help is greatly appreciated. 很明显,flask如何处理应用程序上下文存在一些问题,但是我不太清楚它是如何工作的。任何帮助都将不胜感激。

Traceback says line 65, in backup_data_to_s3 print (g) it means you are using g global object while your app context doesn't push. Traceback line 65, in backup_data_to_s3 print (g)这意味着您正在使用g全局对象,而您的应用程序上下文未推送。 utilities.py could ask for the current app while app doesn't created yet, it means actually you can't use current_app unless you create one. utilities.py可能会在尚未创建应用程序的情况下询问当前应用程序,这意味着实际上除非您创建了一个应用程序,否则您将无法使用current_app。 So in your utilities.py you can do something like this: 因此,在您的Utility.py中,您可以执行以下操作:

from . import create_app

app = create_app("config_name")
app_ctx = app.app_context()
app_ctx.push()

#now you can use g, current_app
print(g)

Note 注意

Even if you run your app with init.py at the same time you would not be able to get current_app in your utilities.py. 即使同时使用init.py运行应用程序,也无法在Utility.py中获取current_app。

When flask get a request it activate application context and after request delete app context. flask收到请求后,它将激活应用程序上下文,并在请求后删除应用程序上下文。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM