Flask-SQLAlchemy 3.0版本
Flask-SQLAlchemy 是 flask 的一個(gè)拓展插件,專(zhuān)門(mén)添加對(duì) SQLAlchemy 的支持(ORM,關(guān)系對(duì)象模型)。使用它可以在 flask 中使用對(duì)象直接與 SQLAlchemy 進(jìn)行交互,大大簡(jiǎn)化了 SQLAlchemy 與 flask 結(jié)合使用的過(guò)程,提供了非常方便的一些操作對(duì)象,例如引擎、模型、會(huì)話(huà)、請(qǐng)求等。
Flask-SQLAlchemy 不會(huì)改變 SQLAlchemy 的工作或使用方式。請(qǐng)參閱 SQLAlchemy 文檔以了解如何深入使用 ORM。此處的文檔僅涵蓋設(shè)置擴(kuò)展,而不涉及如何使用 SQLAlchemy。
注意,sqlalchemy 2.0 之后與之前的 1.4 差距蠻大。flask-sqlalchemy 3.0 版本與之前的差距也蠻大。使用是請(qǐng)注意版本。
快速開(kāi)始
Flask-SQLAlchemy 內(nèi)部封裝了很多 SQLAlchemy 的操作來(lái)簡(jiǎn)化 SQLAlchemy 的使用。雖然新增了一些新的有用的功能,但它仍然可以像 SQLAlchemy 一樣使用。
本頁(yè)將帶你了解 Flask-SQLAlchemy 的基本使用,有關(guān)完整功能和自定義,請(qǐng)參閱文檔的其他部分,包括?SQLAlchemy
?對(duì)象的 API 文檔。
查閱 SQLAlchemy 文檔
Flask-SQLAlchemy 是 SQLAlchemy 的一些操作。你應(yīng)該遵循 SQLAlchemy 的教程來(lái)了解并使用它,請(qǐng)查詢(xún)其文檔獲取有關(guān)功能的詳細(xì)信息。本文展示了如何設(shè)置 Flask-SQLAlchemy 本身,而不是如何使用 SQLAlchemy 。Flask-SQLAlchemy 會(huì)自動(dòng)設(shè)置引擎、聲明模型類(lèi)、作用域會(huì)話(huà),因此你可以跳過(guò) SQLAlchemy 教程的這部分內(nèi)容。
安裝
Flask-SQLAlchemy 在 pypi 上就有,可以直接使用 pip 指令進(jìn)行安裝。例如,要使用最新版本的,可以用 pip 安裝或更新到最新版本。
配置插件
唯一需要的 Flask 應(yīng)用程序配置是?SQLALCHEMY_DATABASE_URI
?鍵。這是一個(gè)連接字符串,它告訴 SQLAlchemy 要連接到哪個(gè)數(shù)據(jù)庫(kù)。
創(chuàng)建 Flask 應(yīng)用程序?qū)ο笾?,加載配置,然后通過(guò)調(diào)用?db.init_app
?使用應(yīng)用程序初始化?SQLAlchemy
?擴(kuò)展類(lèi)。此示例連接到 SQLite 數(shù)據(jù)庫(kù),該數(shù)據(jù)庫(kù)存儲(chǔ)在應(yīng)用程序的實(shí)例文件夾中。
db
?對(duì)象使您可以訪(fǎng)問(wèn)?db.Model
?類(lèi)來(lái)定義模型,并訪(fǎng)問(wèn)?db.session
?來(lái)執(zhí)行查詢(xún)。
有關(guān)鏈接字符串的說(shuō)明以及使用的其他配置鍵,請(qǐng)參閱?配置?,?SQLAlchemy
?對(duì)象還采用一些參數(shù)來(lái)自定義它管理的對(duì)象。
定義模型
子類(lèi)?db.Model
?以定義模型類(lèi)。?db
?對(duì)象使?sqlalchemy
?和?sqlalchemy.orm
?中的名稱(chēng)方便使用,例如?db.Column
?。該模型將通過(guò)將?CamelCase
?類(lèi)名轉(zhuǎn)換為?snake_case
?來(lái)生成表名。
表名?"user"
?將自動(dòng)分配給模型的表。
有關(guān)定義和創(chuàng)建模型和表的更多信息,請(qǐng)參閱模型和表(bilibili 文章無(wú)法插入超鏈接)。
創(chuàng)建表
定義所有模型和表后,調(diào)用?SQLAlchemy.create_all()
?在數(shù)據(jù)庫(kù)中創(chuàng)建表模式。這需要一個(gè)應(yīng)用程序上下文。由于此時(shí)您不在請(qǐng)求中,請(qǐng)手動(dòng)創(chuàng)建一個(gè)。
如果在其他模塊中定義了模型,則必須在調(diào)用?create_all
?之前導(dǎo)入它們,否則 SQLAlchemy 將不知道它們,就不會(huì)創(chuàng)建對(duì)應(yīng)的數(shù)據(jù)表。
數(shù)據(jù)查詢(xún)
在 Flask 視圖或 CLI 命令中,可以使用?db.session
?來(lái)執(zhí)行查詢(xún)和修改模型數(shù)據(jù)。
SQLAlchemy 自動(dòng)為每個(gè)模型定義一個(gè)?__init__
?方法,該方法將任何關(guān)鍵字參數(shù)分配給相應(yīng)的數(shù)據(jù)庫(kù)列和其他屬性。
db.session.add(obj)
?將對(duì)象添加到會(huì)話(huà)中,以便插入。修改對(duì)象的屬性會(huì)更新對(duì)象。?db.session.delete(obj)
?刪除一個(gè)對(duì)象。請(qǐng)記住在修改、添加或刪除任何數(shù)據(jù)后調(diào)用?db.session.commit()
?。
db.session.execute(db.select(...))
?構(gòu)造一個(gè)查詢(xún)以從數(shù)據(jù)庫(kù)中選擇數(shù)據(jù)。構(gòu)建查詢(xún)是 SQLAlchemy 的主要功能,因此你需要閱讀其關(guān)于?select?的教程以了解所有相關(guān)信息。你通常會(huì)使用?Result.scalars()
?方法獲取結(jié)果列表,或使用?Result.scalar()
?方法獲取單個(gè)結(jié)果。
您可能會(huì)看到使用?Model.query
?來(lái)構(gòu)建查詢(xún)。這是一個(gè)較舊的查詢(xún)接口,在 SQLAlchemy 中被認(rèn)為是遺留的。更喜歡使用?db.session.execute(db.select(...))
?。
有關(guān)查詢(xún)的更多信息,請(qǐng)參閱修改和查詢(xún)數(shù)據(jù)。
記住什么
大多數(shù)情況下,您應(yīng)該照常使用 SQLAlchemy。?SQLAlchemy
?擴(kuò)展實(shí)例創(chuàng)建、配置并授予對(duì)以下內(nèi)容的訪(fǎng)問(wèn)權(quán)限:
SQLAlchemy.Model
?聲明模型基類(lèi)。它自動(dòng)設(shè)置表名而不需要?__tablename__
?。SQLAlchemy.session
?是一個(gè)作用域?yàn)楫?dāng)前 Flask 應(yīng)用程序上下文的會(huì)話(huà)。每次請(qǐng)求后都會(huì)清理它。SQLAlchemy.metadata
?和?SQLAlchemy.metadatas
?允許訪(fǎng)問(wèn)配置中定義的每個(gè)元數(shù)據(jù)。SQLAlchemy.engine
?和?SQLAlchemy.engines
?允許訪(fǎng)問(wèn)配置中定義的每個(gè)引擎。SQLAlchemy.create_all()
?創(chuàng)建所有表。您必須處于活動(dòng)的 Flask 應(yīng)用程序上下文中才能執(zhí)行查詢(xún)并訪(fǎng)問(wèn)會(huì)話(huà)和引擎。
模型與數(shù)據(jù)表
使用?db.Model
?類(lèi)定義模型,或使用?db.Table
?類(lèi)創(chuàng)建表。兩者都處理 Flask-SQLAlchemy 的綁定鍵以與特定引擎關(guān)聯(lián)。
定義模型
有關(guān)以聲明方式定義模型類(lèi)的完整信息,請(qǐng)參閱 SQLAlchemy 的?聲明性文檔。
子類(lèi)?db.Model
?以創(chuàng)建模型類(lèi)。這是一個(gè) SQLAlchemy 聲明性基類(lèi),它將采用?Column
?屬性并創(chuàng)建一個(gè)表。與普通 SQLAlchemy 不同,如果未設(shè)置?__tablename__
?并且定義了主鍵列,F(xiàn)lask-SQLAlchemy 的模型將自動(dòng)生成表名。
為方便起見(jiàn),擴(kuò)展對(duì)象提供對(duì)?sqlalchemy
?和?sqlalchemy.orm
?模塊中名稱(chēng)的訪(fǎng)問(wèn)。所以你可以使用?db.Column
?而不是導(dǎo)入和使用?sqlalchemy.Column
?,盡管兩者是等價(jià)的。
定義模型不會(huì)在數(shù)據(jù)庫(kù)中創(chuàng)建它。在定義模型和表后使用?create_all()
?創(chuàng)建它們。如果您在子模塊中定義模型,則必須導(dǎo)入它們,以便 SQLAlchemy 在調(diào)用?create_all
?之前知道它們。
定義表
有關(guān)定義表對(duì)象的完整信息,請(qǐng)參閱 SQLAlchemy 的表文檔。
創(chuàng)建?db.Table
?的實(shí)例來(lái)定義表。該類(lèi)采用表名,然后是任何列和其他表部分,例如列和約束。與普通的 SQLAlchemy 不同,?metadata
?參數(shù)不是必需的。將根據(jù)?bind_key
?參數(shù)選擇元數(shù)據(jù),否則將使用默認(rèn)值。
直接創(chuàng)建表的一個(gè)常見(jiàn)原因是在定義多對(duì)多關(guān)系時(shí)。關(guān)聯(lián)表不需要自己的模型類(lèi),因?yàn)樗鼘⑼ㄟ^(guò)相關(guān)模型上的相關(guān)關(guān)系屬性進(jìn)行訪(fǎng)問(wèn)。
修改與查詢(xún)
增、改、刪
有關(guān)使用 ORM 修改數(shù)據(jù)的更多信息,請(qǐng)參閱 SQLAlchemy 的?ORM 教程?和其他 SQLAlchemy 文檔。
要插入數(shù)據(jù),請(qǐng)將模型對(duì)象傳遞給?db.session.add()
?:
要更新數(shù)據(jù),請(qǐng)修改模型對(duì)象的屬性:
要?jiǎng)h除數(shù)據(jù),將模型對(duì)象傳遞給?db.session.delete()
?:
修改數(shù)據(jù)后,必須調(diào)用?db.session.commit()
?將修改提交到數(shù)據(jù)庫(kù)。否則,它們將在請(qǐng)求結(jié)束時(shí)被丟棄。
查詢(xún)
有關(guān)使用 ORM 查詢(xún)數(shù)據(jù)的更多信息,請(qǐng)參閱 SQLAlchemy 的查詢(xún)指南和其他 SQLAlchemy 文檔。
查詢(xún)通過(guò)?db.session.execute()
?執(zhí)行。它們可以使用?select()
?構(gòu)造。執(zhí)行 select 會(huì)返回一個(gè)?Result
?對(duì)象,該對(duì)象具有許多用于處理返回行的方法。
視圖查詢(xún)
如果您編寫(xiě)一個(gè) Flask 視圖函數(shù),則返回一個(gè)?404 Not Found
?錯(cuò)誤以丟失條目通常很有用。 Flask-SQLAlchemy 提供了一些額外的查詢(xún)方法。
SQLAlchemy.get_or_404()
?如果具有給定 id 的行不存在,?SQLAlchemy.get_or_404()
?將引發(fā) 404,否則它將返回實(shí)例。SQLAlchemy.first_or_404()
?如果查詢(xún)未返回任何結(jié)果,?SQLAlchemy.first_or_404()
?將引發(fā) 404,否則將返回第一個(gè)結(jié)果。SQLAlchemy.one_or_404()
?如果查詢(xún)沒(méi)有準(zhǔn)確返回一個(gè)結(jié)果,?SQLAlchemy.one_or_404()
?將引發(fā) 404,否則將返回結(jié)果。
遺留查詢(xún)接口
您可能會(huì)看到使用?Model.query
?或?session.query
?來(lái)構(gòu)建查詢(xún)。該查詢(xún)接口在 SQLAlchemy 中被認(rèn)為是遺留的。更喜歡使用?session.execute(select(...))
?。 有關(guān)文檔,請(qǐng)參閱舊版查詢(xún)接口。
分頁(yè)查詢(xún)
如果有很多結(jié)果,你可能只想一次顯示特定數(shù)量,允許用戶(hù)單擊下一個(gè)和上一個(gè)鏈接來(lái)查看數(shù)據(jù)頁(yè)面。這有時(shí)稱(chēng)為分頁(yè),并使用?paginate
?實(shí)現(xiàn)。
在 select 語(yǔ)句上調(diào)用?SQLAlchemy.paginate()
?以獲得?Pagination
?對(duì)象。
在請(qǐng)求期間,這將從查詢(xún)字符串?request.args
?中獲取?page
?和?per_page
?參數(shù)。傳遞?max_per_page
?以防止用戶(hù)在單個(gè)頁(yè)面上請(qǐng)求太多結(jié)果。如果未給出,默認(rèn)值為第 1 頁(yè),每頁(yè) 20 個(gè)項(xiàng)目。