Step 4: 请求数据库连接

现在我们知道了怎样建立数据库连接以及在脚本中使用这些连接,但是我们如何能优雅地在请求中这么做? 所有我们的函数中需要数据库连接,因此在请求之前初始化它们,在请求结束后自动关闭他们就很有意义。

Flask 允许我们使用 before_request()after_request()teardown_request() 装饰器来实现这个功能:

@app.before_request
def before_request():
    g.db = connect_db()

@app.teardown_request
def teardown_request(exception):
    g.db.close()

使用 before_request() 装饰器的函数会在请求之前被调用而且不带参数。使用 after_request() 装饰器的函数会在请求之后被调用且传入将要发给客户端的响应。 它们必须返回那个响应对象或是不同的响应对象。但当异常抛出时,它们不一定会被执行, 这时可以使用 teardown_request() 装饰器。它装饰的函数将在响应构造后执行, 并不允许修改请求,返回的值会被忽略。如果在请求已经被处理的时候抛出异常,它会被传递到每个函数, 否则会传入一个 None

我们把当前的数据库连接保存在 Flask 提供的 g 特殊对象中。这个对象只能保存一次请求的信息, 并且在每个函数里都可用。不要用其它对象来保存信息,因为在多线程环境下将不可行。特殊的对象 g 在后台有一些神 奇的机制来保证它在做正确的事情。

请继续浏览 Step 5: 视图函数

Hint

我该把代码放哪里?

如果你一直遵循本教程,你可能会问从这步到下一步,代码放在什么地方。逻辑上应该按照模块来组织函数, 把你新的 before_requestteardown_request 装饰的函数放在之前的 init_db 函数下面(逐行遵照教程)。

如果你需要短时间找到你的思路,请看看 example source 是如何组织的。在 Flask 中,你可以把所有的应用代码放到单个 Python 模块中。但你无需这么做,并且在你的应用 grows larger 的时候,这显然不是个好主意。