烧瓶0.10 mongo在应用程序环境外工作 [英] flask 0.10 mongo working outside of application context

查看:178
本文介绍了烧瓶0.10 mongo在应用程序环境外工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道关于如何处理烧瓶在应用程序环境之外工作的问题很少,但我无法让他们为我工作



我有长时间运行的mongo聚合查询,并计划使用apscheduler定期运行。
下面是我的应用程序结构,但任务失败,出现RuntimeError:在应用程序上下文之外工作。 ihttp://flask.pocoo.org/docs/patterns/sqlite3/有一些关于使用新烧瓶的例子,但是想知道是否有人可以建议如何正确保存全局的mongodb连接并在apscheduler中共享连接

  __ init.py__ 

from app import create_app

$ app $ py

$ $ $ $ $ $ $ $ $ $ $' g
from .extention import mongo,redis,sched
$ b def create_app(config = None):
创建一个Flask应用程序。

app = Flask(__ name__)
configure_extensions(app)
return app
$ b def configure_extensions(app):
mongo.init_app(app)#initialise mongo连接从配置
redis.init_app(app)

从schedule_tasks导入*

extention.py

  from flask.ext.pymongo import PyMongo 
mongo = PyMongo()$ bps
$ from apscheduler.scheduler import Scheduler
config = {'apscheduler.jobstores.file.class':'apscheduler.jobstores.shelve_store:ShelveJobStore',
'apscheduler.jobstores.file.path':'/ tmp / sched_dbfile'}
sched = Scheduler(config)
$ b $ from flask.ext.redis import Redis
redis = Redis()

schedule_tasks.py

  from .extention import mongo 
@sched .interval_schedule(minutes = 1)
def long_running_queries():
## mongo agg query ##
mongo.db.command(aggregate,collection,pipeline =some query )
sched.start()
sched.print_jobs()


解决方案

要理解这个错误,您需要了解应用程序上下文



完全有可能有人编写多个Flask应用程序,它们在同一个进程中处理它们的请求。 举例如下...


$ b从werkzeug.wsgi中导入DispatcherMiddleware
从frontend_app导入应用程序导入应用程序作为前端
从backend_app导入应用程序作为后端

application = DispatcherMiddleware(前端,{
'/ backend':后端
})

请记住,在这种情况下,前端应用程序可以使用不同的Mongo设置,但使用完全相同的Mongo扩展对象。出于这个原因,当你运行一个脚本时,Flask不能认为哪个是当前应用程序。因此,诸如 url_for()之类的东西,或者诸如MongoDB扩展等很多扩展方法都需要知道哪个应用程序在执行任何操作之前是当前应用程序。因此,无论何时您试图使用Flask或扩展函数来执行除了设置应用程序本身(使用配置值等)之外的其他任何操作,都需要明确地告诉Flask当前分配给应用程序上下文的应用程序是什么。



文档提供了一种方法,可以做到这一点。

 #请注意这里的递归导入
来自。导入应用程序
from .extention导入mongo

@ sched.interval_schedule(minutes = 1)
def long_running_queries():
with app.app_context():
mongo.db.command(aggregate,collection,pipeline =some query)



<因此,您需要创建应用程序对象本身,然后使用和app.app_context()行。在声明中,你所有的调用(例如Mongo扩展的调用)都应该可以工作。请注意,您不需要在视图中执行任何操作,因为Flask会自动将所有这些作为处理请求的一部分。


i know there are few question on how to deal with flask "working outside of application context", but i could not get them to work for me

I have a long running mongo aggregation queries and are scheduled to run at regular intervals using apscheduler. Below is my app structure, but the tasks fail with "RuntimeError: working outside of application context". ihttp://flask.pocoo.org/docs/patterns/sqlite3/ has some example on using the new flask.g but wondering if anyone can advise on how to properly save mongodb connection globally and share that connection in apscheduler

__init.py__

from app import create_app

app.py

from flask import Flask, request, render_template,g
from .extention import mongo, redis, sched

def create_app(config=None):
"""Create a Flask app."""

    app = Flask(__name__)
    configure_extensions(app)
    return app

def configure_extensions(app):
    mongo.init_app(app) # initialise mongo connection from the config
    redis.init_app(app)

from schedule_tasks import *

extention.py

from flask.ext.pymongo import PyMongo
mongo = PyMongo()

from apscheduler.scheduler import Scheduler
config = {'apscheduler.jobstores.file.class': 'apscheduler.jobstores.shelve_store:ShelveJobStore',
          'apscheduler.jobstores.file.path': '/tmp/sched_dbfile'}
sched = Scheduler(config)

from flask.ext.redis import Redis
redis = Redis()

schedule_tasks.py

from .extention import mongo
@sched.interval_schedule(minutes=1)
def long_running_queries():
    ## mongo agg query ##
    mongo.db.command("aggregate", "collection", pipeline = "some query" )
sched.start()
sched.print_jobs()

解决方案

To understand this error, you need to understand the application context.

It's entirely possible for someone to write multiple Flask applications that all handle their requests in the same process. The docs give the following example...

from werkzeug.wsgi import DispatcherMiddleware
from frontend_app import application as frontend
from backend_app import application as backend

application = DispatcherMiddleware(frontend, {
    '/backend':     backend
})

Keep in mind that in this case, the frontend app could use different Mongo setups, but use the exact same Mongo extension object. For this reason, Flask cannot assume which is the "current" app when you run a script. Therefore, things such as url_for(), or many of the methods on extensions like the MongoDB extension, need to know which application is the "current" one before they do anything.

Therefore, whenever you are attempting to use Flask or extension functions to do anything other than set up the applications themselves (with configuration values, etc.), you need to explicitly tell Flask what is the current app to assign to the application context.

The docs give a way that you can do this..

# Be careful about recursive imports here
from . import app
from .extention import mongo

@sched.interval_schedule(minutes=1)
def long_running_queries():
    with app.app_context():
        mongo.db.command("aggregate", "collection", pipeline = "some query" )

So, you'll need to create the app object itself, then use the with app.app_context() line. Within that with statement, all of your calls (such as as those to your Mongo extension) should work. Note that you don't need to do any of this in a view because Flask will automatically do all of this as part of it's handling of a request.

这篇关于烧瓶0.10 mongo在应用程序环境外工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆