Flask 应用程序上下文¶
需要一个活动 Flask 应用程序上下文来进行查询并访问 db.engine
和 db.session
。这是因为会话的范围限定在上下文中,以便在每个请求或 CLI 命令后正确清理会话。
无论如何使用扩展初始化应用程序,都不会将其存储以备后用。相反,扩展使用 Flask 的 current_app
代理来获取活动应用程序,而这需要一个活动应用程序上下文。
自动上下文¶
当 Flask 处理请求或 CLI 命令时,将自动推送应用程序上下文。因此,您无需执行任何特殊操作即可在请求或 CLI 命令期间使用数据库。
手动上下文¶
如果您尝试在应用程序上下文不活动时使用数据库,您将看到以下错误。
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.
如果您发现自己处于需要数据库但没有上下文的境况,您可以使用 app_context
推送一个上下文。例如,在调用 db.create_all
以创建表时,这很常见。
def create_app():
app = Flask(__name__)
app.config.from_object("project.config")
import project.models
with app.app_context():
db.create_all()
return app
测试¶
如果您使用 Flask 测试客户端测试您的应用程序以向您的端点发出请求,则上下文将作为请求的一部分可用。如果您需要直接测试有关您的数据库或模型的内容,而不是通过请求,则需要手动推送一个上下文。
仅在每个测试确实需要时,在需要的时间范围内推送上下文。不要为每个测试全局推送应用程序上下文,因为这会干扰会话的清理方式。
def test_user_model(app):
user = User()
with app.app_context():
db.session.add(user)
db.session.commit()
如果您发现自己编写了许多这样的测试,您可以使用 pytest 夹具为特定测试推送上下文。
import pytest
@pytest.fixture
def app_ctx(app):
with app.app_context():
yield
@pytest.mark.usefixtures("app_ctx")
def test_user_model():
user = User()
db.session.add(user)
db.session.commit()