在应用程序上下文之外工作 - Flask

时间:2015-12-06 21:22:43

标签: python flask

def get_db(self,dbfile):
    if hasattr(g, 'sqlite_db'): self.close_db(g.sqlite_db)
    try:
        g.sqlite_db = self.connect_db('{}/{}'.format(app.root_path, dbfile))
    except sqlite3.OperationalError as e:
        raise e

    return g.sqlite_db

嗨,这段代码位于DB类中,我得到的错误是

  

RuntimeError:在应用程序上下文之外工作

此行发生错误

g.sqlite_db = self.connect_db('{}/{}'.format(app.root_path, dbfile))

我认为问题在于g,它是像from flask import g

那样导入的

如何修复此错误? 感谢。

7 个答案:

答案 0 :(得分:10)

也许您需要在应用程序上下文中调用您的函数:

with app.app_context():
  # call your method here

答案 1 :(得分:9)

来自flask/globals.py中的Flask源代码:

_app_ctx_err_msg = '''\
Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in a way.  To solve
this set up an application context with app.app_context().  See the
documentation for more information.\
'''

根据文档,您可以看到需要将flask.current_app指向您的应用程序,而目前却没有。

在Flask初始化之前,您可能正在调用数据库函数。我的猜测是你的app对象尚未使用Flask构造函数创建。

答案 2 :(得分:0)

创建应用时,请使用:

app.app_context().push()

例如这样的

from yourapp import create_app

app = create_app()

app.app_context().push()

for further information

答案 3 :(得分:0)

扩展@VadimK的答案。如果要阻止代码在app_context外部执行,可以使用flask.has_app_context()查看代码当前是否在app context内部:

另请参阅:flask.has_request_context()

答案 4 :(得分:0)

进行一些单元测试时,我遇到了同样的问题。

在我的测试类中添加以下功能解决了我的问题:

@classmethod
def setUpClass(self):
    self.app = create_app("testing")
    self.client = self.app.test_client()

答案 5 :(得分:0)

其他用户已经指出了如何解决眼前的问题,但是您可以考虑修改数据库连接的创建方式来解决此问题。

您不必在数据库类中使用方法来实例化数据库连接,而可以在每次请求之前在控制器中创建连接。然后使用teardown_request装饰器关闭连接。

然后,在路由中,可以将连接传递给DB类,作为实例化新DB对象的一部分。

这将确保您除非需要连接,否则从不创建数据库连接。而且它阻止您从应用程序上下文之外访问Flask全局变量。

@app.before_request
def before_request():
    try:
        g.sqlite_db = self.connect_db('{}/{}'.format(app.root_path, dbfile))
    except sqlite3.OperationalError as e:
        raise e

@app.teardown_request
def teardown_request(e):
    if hasattr(g, 'sqlite_db'): self.close_db(g.sqlite_db)

@app.route('/someroute', methods=["GET"]:
def someroute():
    db_obj = DB(g.sqlite_db)
    .
    .
    .

答案 6 :(得分:-5)

错误:这通常意味着您尝试使用所需的功能 以某种方式与当前应用程序对象进行交互。要解决 这与app.app_context()建立了一个应用程序上下文。见 文档以获取更多信息。