正如之前介紹的,F(xiàn)laskr 是一個數(shù)據(jù)庫驅(qū)動的應(yīng)用,更準(zhǔn)確的說法 是,一個由關(guān)系數(shù)據(jù)庫系統(tǒng)驅(qū)動的應(yīng)用。關(guān)系數(shù)據(jù)庫系統(tǒng)需要一個模 式來決定存儲信息的方式。所以在第一次開啟服務(wù)器之前,要點是創(chuàng) 建模式。

可以通過管道把 schema.sql 作為 sqlite3 命令的輸入來創(chuàng)建這 個模式,命令為如下:

sqlite3 /tmp/flaskr.db < schema.sql

這種方法的缺點是需要安裝 sqlite3 命令,而并不是每個系統(tǒng)都有安 裝。而且你必須提供數(shù)據(jù)庫的路徑,否則將報錯。用函數(shù)來初始化數(shù)據(jù) 庫是個不錯的想法。

要這么做,我們可以創(chuàng)建一個名為 init_db 的函數(shù)來初始化數(shù)據(jù)庫。 讓我們首先看看代碼。只需要把這個函數(shù)放在 flaskr.py 里的 connect_db 函數(shù)的后面:

def init_db():
    with app.app_context():
        db = get_db()
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()

那么,這段代碼會發(fā)生什么?還記得嗎?上個章節(jié)中提到,應(yīng)用環(huán)境在 每次請求傳入時創(chuàng)建。這里我們并沒有請求,所以我們需要手動創(chuàng)建一 個應(yīng)用環(huán)境。 g 在應(yīng)用環(huán)境外無法獲知它屬于哪個應(yīng) 用,因為可能會有多個應(yīng)用同時存在。

with app.app_context() 語句為我們建立了應(yīng)用環(huán)境。在 with 語句的內(nèi)部, g 對象會與 app 關(guān)聯(lián)。在語句的 結(jié)束處,會釋放這個關(guān)聯(lián)兵執(zhí)行所有銷毀函數(shù)。這意味著數(shù)據(jù)庫連接在 提交后斷開。

應(yīng)用對象的 open_resource() 方法是一個很方便 的輔助函數(shù),可以打開應(yīng)用提供的資源。這個函數(shù)從資源所在位置( 你的 flaskr 文件夾)打開文件,并允許你讀取它。我們在此用它來 在數(shù)據(jù)庫連接上執(zhí)行腳本。

SQLite 的數(shù)據(jù)庫連接對象提供了一個游標(biāo)對象。游標(biāo)上有一個方法可 以執(zhí)行完整的腳本。最后我們只需提交變更。SQLite 3 和其它支持事 務(wù)的數(shù)據(jù)庫只會在你顯式提交的時候提交。

現(xiàn)在可以在 Python shell 導(dǎo)入并調(diào)用這個函數(shù)來創(chuàng)建數(shù)據(jù)庫:

>>> from flaskr import init_db
>>> init_db()

故障排除

如果你遇到了表無法找到的異常,請檢查你是否確實調(diào)用過 init_db 函數(shù)并且表的名稱是正確的(比如弄混了單數(shù)和復(fù)數(shù))。

閱讀 Flask 視圖函數(shù) 以繼續(xù)。