2013-08-28 19 views
3

我知道有關於如何處理燒瓶幾個問題「工作的應用程序上下文之外」,但我不能讓他們爲我工作瓶0.10蒙戈工作應用程序上下文之外

我有一個長期運行mongo聚合查詢,並計劃使用apscheduler定期運行。 以下是我的應用程序結構,但任務因「RuntimeError:在應用程序上下文之外工作」而失敗。 ihttp://flask.pocoo.org/docs/patterns/sqlite3/有一些使用新燒瓶的例子,但是想知道是否有人可以建議如何在全球範圍內正確保存mongodb連接並在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() 
+0

究竟是哪一行拋出了RuntimeError?你可以把一個完整的堆棧跟蹤? –

+0

我得到的錯誤是「引發RuntimeError('在應用程序上下文外部工作')」文件「schedule_tasks.py」,第5行,在mongo – Linus

回答

5

要了解此錯誤,您需要了解application context

完全有可能有人編寫多個Flask應用程序,這些應用程序都在同一個進程中處理它們的請求。該文檔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 
}) 

請記住,在這種情況下,前端應用程序可以使用不同的設置蒙戈,但使用完全相同的蒙戈擴展對象。出於這個原因,當你運行一個腳本時,Flask不能認爲哪個是「當前」應用程序。因此,諸如url_for()之類的東西,或許多像MongoDB擴展那樣的擴展方法,在他們做任何事之前都需要知道哪個應用程序是「當前」應用程序。因此,無論您何時嘗試使用Flask或擴展函數來執行除設置應用程序本身之外的其他任何操作(包括配置值等),都需要明確告訴Flask當前分配給應用程序的應用程序是什麼application context

該文檔給出一種方式,你可以做到這一點..

# 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") 

所以,你需要創建應用程序對象本身,然後使用with app.app_context()線。在聲明中,您的所有呼叫(例如您的Mongo擴展的呼叫)都應該有效。請注意,您不需要在視圖中執行任何操作,因爲Flask會在處理請求時自動執行所有這些操作。