4

「アプリケーションコンテキストの外部で動作する」フラスコを処理する方法についていくつかの質問があることは知っていますが、それらを動作させることができませんでした

長時間実行されている mongo 集計クエリがあり、apscheduler を使用して定期的に実行するようにスケジュールされています。以下は私のアプリの構造ですが、タスクは「RuntimeError: working outside of application context」で失敗します。ihttp://flask.pocoo.org/docs/patterns/sqlite3/には、新しいflask.gの使用例がいくつかありますが、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 *

extension.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()
4

1 に答える 1

5

このエラーを理解するには、アプリケーション コンテキストを理解する必要があります。

同じプロセスですべてのリクエストを処理する複数の Flask アプリケーションを作成することは誰にとっても十分に可能です。ドキュメントは次の例を示しています...

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

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

この場合、フロントエンド アプリは異なる Mongo セットアップを使用できますが、まったく同じ Mongo 拡張オブジェクトを使用することに注意してください。このため、Flask は、スクリプトを実行するときに、どれが「現在の」アプリであるかを推測できません。したがって、url_for()、または MongoDB 拡張機能のような拡張機能の多くのメソッドは、何かを実行する前に、どのアプリケーションが「現在の」アプリケーションであるかを知る必要があります。

したがって、Flask または拡張関数を使用してアプリケーション自体をセットアップする以外のことをしようとするときはいつでも (構成値などを使用して)、Flask にアプリケーション コンテキストに割り当てる現在のアプリを明示的に伝える必要があります。

ドキュメントは、これを行う方法を提供します..

# 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()行を使用する必要があります。その with ステートメント内で、すべての呼び出し (Mongo 拡張機能への呼び出しなど) が機能するはずです。ビューでこれを行う必要はないことに注意してください。これは、Flask がリクエスト処理の一部としてこれらすべてを自動的に行うためです。

于 2013-08-30T00:00:39.377 に答える