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
如何修复此错误? 感谢。
答案 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()
答案 3 :(得分:0)
扩展@VadimK的答案。如果要阻止代码在app_context
外部执行,可以使用flask.has_app_context()查看代码当前是否在app 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()建立了一个应用程序上下文。见 文档以获取更多信息。