### 导航
- [索引](# "总目录")
- [下一页](# "在 Flask 中使用 SQLAlchemy") |
- [上一页](# "使用 Fabric 部署") |
- [Flask 0.10.1 文档](#) »
- [Flask 代码模式](#) »
# 在 Flask 中使用 SQLite 3
在 Flask 中,在请求开始的时候用 [before_request()](# "flask.Flask.before_request") 装饰器实现打开数据库连接的代码,然后在请求结束的时候用 [before_request()](# "flask.Flask.before_request")装饰器关闭数据库连接。在这个过程中需要配合 [g](# "flask.g") 对象。
于是,在 Flask 里一个使用 SQLite 3 的简单例子就是下面这样:
~~~
import sqlite3
from flask import g
DATABASE = '/path/to/database.db'
def connect_db():
return sqlite3.connect(DATABASE)
@app.before_request
def before_request():
g.db = connect_db()
@app.teardown_request
def teardown_request(exception):
if hasattr(g, 'db'):
g.db.close()
~~~
注解
请记住,teardown request 在请求结束时总会运行,即使 before-request 处理器运行失败或者从未运行过。我们需要确保数据库连接在关闭的时候在那里。
### 按需连接
上述方法的缺陷在于,它只能用于 Flask 会执行 before-request 处理器的场合下有效,如果您想要在一个脚本或者 Python 的交互式终端中访问数据库。那么您必须做一些类似下面的代码的事情:
~~~
with app.test_request_context():
app.preprocess_request()
# now you can use the g.db object
~~~
为了激发连接代码的执行,使用这种方式的话,您将不能离开对请求上下文的依赖。但是您使用以下方法可以使应用程序在必要时才连接:
~~~
def get_connection():
db = getattr(g, '_db', None)
if db is None:
db = g._db = connect_db()
return db
~~~
缺点就是,您必须使用 db=get_connection() 而不是仅仅直接使用 g.db来访问数据库连接。
### 简化查询
现在在每个请求处理函数里,您都可以访问 g.db 来获得当前打开的数据库连接。此时,用一个辅助函数简化 SQLite 的使用是相当有用的:
~~~
def query_db(query, args=(), one=False):
cur = g.db.execute(query, args)
rv = [dict((cur.description[idx][0], value)
for idx, value in enumerate(row)) for row in cur.fetchall()]
return (rv[0] if rv else None) if one else rv
~~~
相比起直接使用原始的数据指针和连接对象。这个随手即得的小函数让操作数据库的操作更为轻松。像下面这样使用它:
~~~
for user in query_db('select * from users'):
print user['username'], 'has the id', user['user_id']
~~~
如果您只希望得到一个单独的结果:
~~~
user = query_db('select * from users where username = ?',
[the_username], one=True)
if user is None:
print 'No such user'
else:
print the_username, 'has the id', user['user_id']
~~~
将变量传入 SQL 语句时,使用在语句之前使用一个问号,然后将参数以链表的形式穿进去。永远不要直接将他们添加到 SQL 语句中以字符串形式传入,这样做将会允许恶意用户以 [SQL 注入](http://en.wikipedia.org/wiki/SQL_injection) [http://en.wikipedia.org/wiki/SQL_injection] 的方式攻击您的应用。
### 初始化数据库模型
关系数据库需要一个模型来定义储存数据的模式,所以应用程序通常携带一个schema.sql 文件用于创建数据库。提供一个特定的函数来创建数据库是个不错的主意,以下的函数就能为您做到这件事:
~~~
from contextlib import closing
def init_db():
with closing(connect_db()) as db:
with app.open_resource('schema.sql') as f:
db.cursor().executescript(f.read())
db.commit()
~~~
然后您就可以在 Python 的交互式终端中创建一个这样的数据库:
~~~
>>> from yourapplication import init_db
>>> init_db()
~~~
© 版权所有 2013, Armin Ronacher.
- 欢迎使用 Flask
- 前言
- 给有经验程序员的前言
- 安装
- 快速入门
- 教程
- 介绍 Flaskr
- 步骤 0: 创建文件夹
- 步骤 1: 数据库模式
- 步骤 2: 应用设置代码
- 步骤 3: 创建数据库
- 步骤 4: 请求数据库连接
- 步骤 5: 视图函数
- 步骤 6: 模板
- 步骤 7: 添加样式
- 福利: 应用测试
- 模板
- 测试 Flask 应用
- 记录应用错误
- 配置处理
- 信号
- 即插视图
- 应用上下文
- 请求上下文
- 用蓝图实现模块化的应用
- Flask 扩展
- 与 Shell 共舞
- Flask 代码模式
- 大型应用
- 应用程序的工厂函数
- 应用调度
- 使用 URL 处理器
- 部署和分发
- 使用 Fabric 部署
- 在 Flask 中使用 SQLite 3
- 在 Flask 中使用 SQLAlchemy
- 上传文件
- 缓存
- 视图装饰器
- 使用 WTForms 进行表单验证
- 模板继承
- 消息闪现
- 用 jQuery 实现 Ajax
- 自定义错误页面
- 延迟加载视图
- 在 Flask 中使用 MongoKit
- 添加 Favicon
- 数据流
- 延迟请求回调
- 添加 HTTP Method Overrides
- 请求内容校验码
- 基于 Celery 的后台任务
- 部署选择
- mod_wsgi (Apache)
- 独立 WSGI 容器
- uWSGI
- FastCGI
- CGI
- 聚沙成塔
- API
- JSON 支持
- Flask 中的设计决策
- HTML/XHTML 常见问题
- 安全注意事项
- Flask 中的 Unicode
- Flask 扩展开发
- Pocoo 风格指引
- Python 3 支持
- 升级到最新版本
- Flask Changelog
- 许可证
- 术语表