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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34122949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:29:24  来源:igfitidea点击:

working outside of application context - Flask

pythonflask

提问by Koten

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

Hi this code is located inside DB class, The error I get is

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

RuntimeError: working outside of application context

运行时错误:在应用程序上下文之外工作

the error occurs on this line

错误发生在这一行

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

I think the problem is with g, it is imported like that from flask import g

我认为问题出在 g 上,它是这样导入的 from flask import g

How this error can be fixed? Thanks.

如何修复此错误?谢谢。

采纳答案by Juan Pablo Santos

From the Flask source code in flask/globals.py:

来自 Flask 源代码flask/globals.py

_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.\
'''

Following the documentation, you can see that you need to make flask.current_apppoint to your application and it currently doesn't.

按照文档,您可以看到您需要flask.current_app指出您的应用程序,而目前还没有。

You're probably calling your DB function before Flask has initialized. My guess is that your appobject has not been created yet with the Flaskconstructor.

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

回答by VadimK

Maybe you need to call your function inside an application context:

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

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

回答by Linden

ERROR: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.

错误:这通常意味着您尝试使用需要以某种方式与当前应用程序对象交互的功能。要解决此问题,请使用 app.app_context() 设置应用程序上下文。有关更多信息,请参阅文档。

回答by Сергей Осечкин

When creating your app, use:

创建应用程序时,请使用:

app.app_context().push()

for example like this:

例如像这样:

from yourapp import create_app

app = create_app()

app.app_context().push()

for further information

了解更多信息

回答by user2682863

To expand on @VadimK's answer. If you want to prevent your code from executing outside of an app_contextyou can use flask.has_app_context()to see if the code is currently inside an app context:

扩展@VadimK 的答案。如果您想阻止您的代码在外部执行,app_context您可以使用flask.has_app_context()来查看代码当前是否在应用程序上下文中

See also: flask.has_request_context()

另见:flask.has_request_context()

回答by Cyrus

I had the same issue while doing some unit testing.

我在做一些单元测试时遇到了同样的问题。

Adding the following function to my test class solved my issue:

将以下函数添加到我的测试类解决了我的问题:

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

回答by steve

Other users have pointed out how to solve the immediate problem, however you might consider modifying how the database connection is created to solve this issue.

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

Instead of having a method within you DB class instantiate the database connection you could have the connection created in the controller before every request. Then use the teardown_request decorator to close the connection.

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

Then when within a route you could pass the connection to the DB class as part of instantiating a new DB object.

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

This would ensure that you never create a database connection unless you need one. And it prevent you from accessing Flask globals out of the app context.

这将确保您永远不会创建数据库连接,除非您需要它。它会阻止您在应用程序上下文之外访问 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)
    .
    .
    .