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:可擴展的元學習演算法