當前位置:
首頁 > 知識 > Flask 進階系列:SQLAlchemy 擴展學習

Flask 進階系列:SQLAlchemy 擴展學習

熟悉 Java 的朋友們一定使用過 Hibernate 或 MyBatis 吧,這類的框架稱為對象關係映射 ORM 框架,它將對資料庫的操作從繁瑣的 SQL 語言執行簡化為對象的操作。Python 中也有類似的 ORM 框架,叫 SQLAlchemy。本篇我們將介紹 Flask 中支持 SQLAlchemy 框架的第三方擴展,Flask-SQLAlchemy。

安裝和啟用

在閱讀此文之前,強烈建議讀者先了解 SQLAlchemy 的基本知識。

我們依然通過 pip 安裝:

PyPI 自動會將其所依賴的 SQLAlchemy 包裝上。我們可以採用下面的方法初始化一個 Flask-SQLAlchemy 的實例:

應用配置項"SQLALCHEMYDATABASEURI"指定了 SQLAlchemy 所要操作的資料庫的連接字元串,本文中我們使用 SQLite3,連接字元串以"sqlite:///"開頭,後面的"db/users.db"表示資料庫文件是當前位置下 db 子目錄中的"users.db"文件。

定義模型

一個模型即對應資料庫中的一個表,這裡我們來定義一個用戶模型:

模型類必須繼承"db.Model", db 即上一節的"db = SQLAlchemy(app)",上例中的 User 模型將自動映射到資料庫中的"user"表。User 模型中定義了三個屬性:

"id":整型主鍵

"name":最大長度為 50 的字元串,且值唯一

"age":整型

這三個屬性將分別對應"user"表中"id"主鍵, "name"和"age"欄位。寫好"init()"和"repr"() 方法,我們的模型就定義完成了。現在你就可以通過下面的代碼來創建資料庫和表:

讓我們來驗證下,"user"表是否創建成功。首先打開資料庫文件:

查詢下"user"表的 schema:

你應該可以看到下面的信息:

另外,你可以通過"db.drop_all()"方法刪除所有的表,不過資料庫文件將會被保留。

添加數據

數據表創建完後,讓我們添加些數據進去:

查詢數據

每個數據模型都有"query"介面可以用來查詢模型所對應的表的記錄。比如,查詢"user"表中的所有記錄:

返回的 users 是一個列表,其中每個元素都是一個 User 類型的對象,對應於"user"表中的一條記錄。該方法相當於執行了 SQL 語句:

"query"介面擁有豐富的方法,這裡列舉一些常用的:

"filter_by()"方法,對查詢結果過濾,參數必須是鍵值對"key=value"

效果相當於使用了 WHERE 子句,多個鍵值對用逗號分割。

"filter()"方法,對查詢結果過濾,比"filter_by()"方法更強大,參數是布爾表達式

多個查詢條件用逗號分割。

"first()"方法,取返回列表中的第一個元素,當我們只查詢一條記錄時非常有用

"order_by()"方法,排序

"limit()"和"offset()"方法,分頁

等同於 MySQL 中的 LIMIT 和 OFFSET,上例中我們從第 11 條記錄開始取,並最多只取 10 條。

"slice(start, stop)",分頁

從 start 位置開始取記錄,到 stop 位置前結束。本質上來說,SQLAlchemy 會將其翻譯成 LIMIT/OFFSET 語句來實現,上例中的"slice(1, 3)"等同於"LIMIT 2 OFFSET 1″。

更新數據

在添加數據時,我們使用了"add()"方法,其實它一樣可以用來更新數據:

SQLAlchemy 會自動判斷,如果對象對應的記錄已存在,就更新而不是添加。

SQLAlchemy 還支持批量更新,比如我們要將所有歲數小於 20 的人都加 1 歲:

更新完後,別忘了提交事務。

刪除數據

只需調用"delete()"方法即可,傳入的參數是對應資料庫中記錄的對象。記得同"add()"一樣,要調用"commit()"來提交事務:

一對多關係

現在讓我們再添加一個模型,成績單。每個用戶對於不同的課程,會有不同的分數,這樣用戶同成績單之前就是一對多的關係。怎麼在模型類的定義中體現這個一對多關係呢。保持 User 類不變,現在讓我們添加一個 Score 類:

Score 模型中有這些屬性:

"id":整型主鍵

"course":最大長度為 50 的字元串

"assess_date":日期時間類型

"score":浮點型

"is_pass":布爾型

分別對應資料庫"score"表中"id"主鍵, "course", "accessdate", "score"和"ispass"欄位。另外,它還有兩個屬性:

"user_id":整型外鍵,對應於"user"表的主鍵"id"

"user":User 對象

"user_id"欄位聲明了外鍵,也就相當於聲明了"user"表同"score"表的一對多關係。"user"屬性並不是數據表中的欄位,它使用了"db.relationship()"方法,使得我們可以通過"Score.user"訪問當前 score 記錄的 user 對象,它的第一個參數"User"就表明了對應的對象模型是 User。而第二個參數"backref"定義了從 User 模型反向引用 Score 模型的方法,上例中,我們就可以用"User.scores"獲取當前 user 對象所有的 score 記錄,它是一個列表。"db.backref()"方法的"lazy"參數決定了在 User 對象中什麼時候載入其 scores 列表的值,延遲載入可以提高性能,並避免內存的浪費,"lazy"參數的選擇可以 參閱這裡。

現在查詢下"score"表的 schema,你會看到下面的結果:

讓我們添加些 score 記錄:

然後試試通過"User.scores"查詢某個用戶的成績:

對於多對多關係,大家可以創建一個單獨的關係表,然後每個表同這個關係表都是一對多的關係。或者大家可以參考 官方文檔上的例子來實現多對多關係。

更多參考資料

SQLAlchemy 的官方文檔

Flask-SQLAlchemy 的官方文檔

Flask-SQLAlchemy 的源碼

題圖:pexels,CC0 授權。

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 編程派 的精彩文章:

利用VPS下載YouTube視頻並上傳至百度雲網盤
Flask 插件學習:Flask-WTF和WTForms 擴展
用 TensorFlow 讓機器人唱首歌給你聽
如何開發一個 PyCharm 插件?

TAG:編程派 |

您可能感興趣

Universal Laser Systems(R)的ULTRA平台系列擴展了材料處理的激光器系統組合
社交VR遊戲《Wands》擴展對Mirage Solo和Oculus Go的支持
使用Burpsuite擴展Hackvertor繞過WAF並解密XOR
FacexWorm通過Facebook Messenger和Chrome擴展傳播
谷歌開源 TF-Ranking:專用於排序學習的可擴展 TensorFlow 庫
微軟愛開源:VS Code擴展Web Template Studio
微軟收購Citus Data擴展PostgreSQL服務
Google Chrome的Windows Timeline擴展重新上架
Github項目推薦 Pytorch TVM 擴展
賽門鐵克發Edge擴展「Norton Safe Web」
美高森美和SiFive推出HiFive Unleashed擴展板助力Linux軟體和固件開發人員首次構建RISC-V PC
iPhoneXR的Touch在iOS 中得到擴展
擴展Zuul實現ignored-patterns的byPass功能
如何擴展 Create React App 的 Webpack 配置
Eur Arch Otorhinolaryngol:單邊耳蝸移植標準擴展研究
EFCore擴展Update方法(實現 Update User SET Id = Id + 1)
Kotlin 擴展
VMware擴展VMware Cloud on AWS服務 引入RDS資料庫
CEVA宣布收購Hillcrest Labs,以擴展其智能感測產品線
OpenAI提出Reptile:可擴展的元學習演算法