### 導航
- [索引](# "總目錄")
- [下一頁](# "在 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
- 許可證
- 術語表