摘要:數(shù)據(jù)庫關(guān)系數(shù)據(jù)庫將數(shù)據(jù)保存在表中來模擬應(yīng)用程序中不同的實(shí)體。這些行之間的連接稱作關(guān)系,也是關(guān)系數(shù)據(jù)庫模型的基礎(chǔ)。就像這個示例中看到的那樣,關(guān)系數(shù)據(jù)庫存儲數(shù)據(jù)高效且避免重復(fù)。最好的例子就是,支持一組關(guān)系數(shù)據(jù)庫引擎,包括流行的和。
數(shù)據(jù)庫就是有組織的存儲應(yīng)用程序數(shù)據(jù),然后查詢檢索指定需要的那部分。大部分web應(yīng)用程序都采用基于關(guān)系模型的數(shù)據(jù)庫,也稱作結(jié)構(gòu)化查詢語言(SQL)數(shù)據(jù)庫。但是最近幾年面向文檔數(shù)據(jù)庫和鍵值數(shù)據(jù)庫(通常稱作NoSQL數(shù)據(jù)庫),成為非常流行的替代者。個人推薦《七周七數(shù)據(jù)庫》這本書,它對各種類型的數(shù)據(jù)庫、應(yīng)用場景和多種不同類型數(shù)據(jù)庫配合使用有比較好的講解。
1、SQL數(shù)據(jù)庫關(guān)系數(shù)據(jù)庫將數(shù)據(jù)保存在表中來模擬應(yīng)用程序中不同的實(shí)體。例如,一個訂單管理應(yīng)用程序數(shù)據(jù)庫可能會有customers、products和orders表。
一個表有一個固定數(shù)量的列和一個可變的行數(shù)。列定義了數(shù)據(jù)表所代表的實(shí)體的屬性。例如,customers表會有name、address、phone等列。表中的每一行定義了由所有列的值組成的實(shí)際數(shù)據(jù)元素。
表有種特殊列稱作主鍵,它持有一個惟一的標(biāo)識符為表中存儲的每一行。表也可以有外鍵,用于引用其他表的主鍵。這些行之間的連接稱作關(guān)系,也是關(guān)系數(shù)據(jù)庫模型的基礎(chǔ)。
圖像5-1展示了存儲users和roles表的簡單數(shù)據(jù)庫圖。連接兩個表的線代表兩個表之間的關(guān)系。
圖像5-1. 關(guān)系數(shù)據(jù)庫示例
在這個數(shù)據(jù)庫表中,roles表存儲了一組所有可能的用戶角色,每一個都被定義為唯一id值——也是表的主鍵。users表包含一組用戶,同樣每一個都有唯一id值。除了主鍵id,roles表還有name列,而users表還有username和password列。在users表中的role_id列是一個引用role表中id列的外鍵,以這種方式確立分配給每個用戶的角色。
就像這個示例中看到的那樣,關(guān)系數(shù)據(jù)庫存儲數(shù)據(jù)高效且避免重復(fù)。重命名用戶角色在這個數(shù)據(jù)庫中會變得異常簡單,因?yàn)榻巧4嬖诙鄮У牡胤?。?dāng)roles表中的角色名發(fā)生改變,所有用戶持有的role_id引用的角色會立即看到這些變化。
而另一方面,將數(shù)據(jù)拆分到多個表中則會變得更加復(fù)雜。生成一組用戶及其角色會產(chǎn)生一個小問題,因?yàn)橛脩艉陀脩艚巧枰獜膬蓮埍碇凶x,且只有連接后才能一起出現(xiàn)。當(dāng)需要的時(shí)候關(guān)系數(shù)據(jù)庫引擎會提供支持來執(zhí)行兩個表的連接操作。
2、NoSQL數(shù)據(jù)庫與上一節(jié)描述相反的、非關(guān)系模型的數(shù)據(jù)庫被統(tǒng)稱為NoSQL數(shù)據(jù)庫。NoSQL數(shù)據(jù)庫常見的組織方式是使用collections代替表、documents代替記錄。NoSQL數(shù)據(jù)庫的設(shè)計(jì)方式使得連接會很復(fù)雜,所以大部分都不支持這個操作。圖像5-1如果用NoSQL數(shù)據(jù)庫結(jié)構(gòu)來表達(dá)則是這樣的:列出用戶及他們的角色,需要應(yīng)用程序自己通過讀取每個用戶的role_id字段去執(zhí)行連接操作,然后查找roles表。
圖像5-2展示了更接近NoSQL數(shù)據(jù)庫的設(shè)計(jì)思想。這個操作運(yùn)用了一個被稱為反模式的思想,減少了表的數(shù)量卻增加了重復(fù)數(shù)據(jù)。
圖像5-2. NoSQL數(shù)據(jù)庫示例
這種結(jié)構(gòu)的數(shù)據(jù)庫為每個用戶顯式的存儲用戶角色名。重命名角色名絕對是一項(xiàng)昂貴的操作,可能需要更新大量的文檔。
但對于NoSQL數(shù)據(jù)庫這并不都是壞消息。雖然有重復(fù)的數(shù)據(jù),但是查詢速度快,因?yàn)椴恍枰B接,可以直接列出用戶和他們的角色。
3、SQL還是NoSQLSQL數(shù)據(jù)庫擅長以高效、緊湊的形式存儲結(jié)構(gòu)化數(shù)據(jù)。這些數(shù)據(jù)庫竭盡全力保持一致性。NoSQL數(shù)據(jù)庫會放低一些一致性要求,因此在性能上有更大的優(yōu)勢。
全面分析和比較數(shù)據(jù)庫類型已經(jīng)超出了本教程的范圍。對于中小型應(yīng)用程序SQL數(shù)據(jù)庫和NoSQL數(shù)據(jù)庫完全可以勝任,且性能幾乎差不多。
4、Python數(shù)據(jù)庫框架Python有大部分的數(shù)據(jù)庫引擎包,包括開源的和商業(yè)的。Flask在可使用的數(shù)據(jù)庫包上沒有限制,所以你可以使用MySQL、Postgres、SQLite、Redis、MongoDB或者CouchDB中你喜歡的任何一個。
如果這些還不夠,也有大量的數(shù)據(jù)庫抽象層包,如SQLAlchemy或MongoEngine讓你像操作常規(guī)Python對象那樣,而不是數(shù)據(jù)庫實(shí)體表、文檔或查詢語句。
在選擇數(shù)據(jù)庫框架的時(shí)候需要評估許多因素:
易用性
如果直接比較數(shù)據(jù)庫引擎和數(shù)據(jù)庫抽象層,第二者明顯勝出。抽象層又稱作對象關(guān)系映射(ORM)或?qū)ο笪臋n映射(ODM),提供從高級面向?qū)ο蟛僮鞯降讓訑?shù)據(jù)庫指令的透明轉(zhuǎn)換。
性能
ORM和ODM的轉(zhuǎn)化需要從對象域轉(zhuǎn)化為數(shù)據(jù)庫域,所以會有一些開銷。大多數(shù)情況下,性能損耗是微不足道的,但總有例外。一般來說,ORM和ODM獲得的生產(chǎn)力遠(yuǎn)遠(yuǎn)超過了性能下降的那部分,所以這不是一個有效的論點(diǎn)來完全拋棄ORM和ODM。應(yīng)該關(guān)心的是選擇怎樣的數(shù)據(jù)庫抽象層,提供可訪問底層數(shù)據(jù)庫中特定操作,就像本地?cái)?shù)據(jù)庫指令那樣實(shí)現(xiàn)的抽象層最佳。
可移植性
數(shù)據(jù)庫的選擇必須考慮開發(fā)和生產(chǎn)平臺。例如,如果你計(jì)劃在云主機(jī)上托管應(yīng)用程序,那么你應(yīng)該找出提供該服務(wù)的數(shù)據(jù)庫。
另一方面ORM和ODM的可移植性不錯。盡管一些框架只為單個數(shù)據(jù)庫引擎提供抽象層,有些抽象層更高級,可以選擇哪種數(shù)據(jù)庫引擎且訪問使用的是同一個面向?qū)ο蟮慕涌?。最好的例子就是SQLAlchemy ORM,支持一組關(guān)系數(shù)據(jù)庫引擎,包括流行的MySQL、Postgres和SQLite。
Flask集成
選擇一個集成了Flask的框架并不是必須的,但是可以不用自己寫集成代碼。Flask集成可以簡化配置和操作,所以應(yīng)該優(yōu)先使用專門設(shè)計(jì)的Flask擴(kuò)展包。
基于這些目的,F(xiàn)lask-SQLAlchemy將是本書示例中應(yīng)該選擇的數(shù)據(jù)庫框架,它對SQLAlchemy進(jìn)行了封裝。
5、使用Flask-SQLAlchemy管理數(shù)據(jù)庫Flask-SQLAlchemy是一個Flask擴(kuò)展,它簡化了在Flask應(yīng)用程序中對SQLAlchemy的使用。SQLAlchemy是一個強(qiáng)大的關(guān)系數(shù)據(jù)庫框架,支持一些數(shù)據(jù)庫后端。提供高級的ORM和底層訪問數(shù)據(jù)庫的本地SQL功能。
和其他擴(kuò)展一樣,通過pip安裝Flask-SQLAlchemy:
(venv) $ pip install flask-sqlalchemy
在Flask-SQLAlchemy,數(shù)據(jù)庫被指定為URL。表格5-1列出三個最受歡迎的數(shù)據(jù)庫引擎url的格式。
表格5-1. Flask-SQLAlchemy數(shù)據(jù)URLs
在這些URL中,hostname是指托管MySQL服務(wù)的服務(wù)器,可能是本地(localhost)又或是遠(yuǎn)程服務(wù)器。數(shù)據(jù)庫服務(wù)器可以托管多個數(shù)據(jù)庫,所以database指出要使用的數(shù)據(jù)庫名。數(shù)據(jù)庫需要身份驗(yàn)證,username和 password是數(shù)據(jù)庫用戶憑證。
注:> SQLite數(shù)據(jù)庫沒有服務(wù),所以hostname、username和password可以缺省且數(shù)據(jù)庫是一個磁盤文件名。
應(yīng)用程序數(shù)據(jù)庫URL必須在Flask配置對象中的SQLALCHEMY_DATABASE_URI鍵中進(jìn)行配置。另一個有用的選項(xiàng)是SQLALCHEMY_COMMIT_ON_TEARDOWN,可以設(shè)置為True來啟用自動提交數(shù)據(jù)庫更改在每個請求中。查閱Flask-SQLAlchemy文檔獲取更多其他配置選項(xiàng)。示例5-1展示如何初始化并配置簡單的SQLite數(shù)據(jù)庫。
示例5-1. hello.py:數(shù)據(jù)庫配置
from flask.ext.sqlalchemy import SQLAlchemy basedir = os.path.abspath(os.path.dirname(__file__)) app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + os.path.join(basedir, "data.sqlite") app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True db = SQLAlchemy(app)
由SQLAlchemy實(shí)例化的db對象表示數(shù)據(jù)庫且提供訪問Flask-SQLAlchemy的所有功能。
6、模型定義模型是指由應(yīng)用程序使用的持久化實(shí)體。在ORM的背景下,一個模型通常是一個帶有屬性的Python類,其屬性與數(shù)據(jù)庫表的列相匹配對應(yīng)。Flask-SQLAlchemy數(shù)據(jù)庫實(shí)例提供了一個基類以及一組輔助類和函數(shù)用于定義它的結(jié)構(gòu)。表格5-1中的roles表和users表可以定義為Role模型和User模型如示例5-2所示。
示例5-2.hello.py:Role模型和User模型定義
class Role(db.Model): __tablename__ = "roles" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) def __repr__(self): return "" % self.name class User(db.Model): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True, index=True) def __repr__(self): return " " % self.username
__tablename__類變量定義數(shù)據(jù)庫中表的名稱。如果__tablename__缺省Flask-SQLAlchemy會指定默認(rèn)的表名,但是這些缺省名稱不遵守使用復(fù)數(shù)命名的約定,所以最好是顯式命名表名。其余的變量是模型的屬性,被定義為db.Column類的實(shí)例。
傳給db.Column構(gòu)造函數(shù)的第一個參數(shù)是數(shù)據(jù)庫列的類型也就是模型屬性的數(shù)據(jù)類型。表格5-2列出一些可用的列的類型,也是用于模型中的Python類型。
表格5-2. 最常見的SQLAlchemy列類型
db.Column剩余的參數(shù)為每個屬性指定了配置選項(xiàng)。表格5-3列出一些可用的選項(xiàng)。
表格5-3. 最常見的SQLAlchemy列選項(xiàng)
注:Flask-SQLAlchemy需要給所有的模型定義主鍵列,通常命名為id。
兩個模型都包含了repr()方法來給它們顯示一個可讀字符串,雖然不是完全必要,不過用于調(diào)試和測試還是很不錯的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/37471.html
摘要:每個表單域都可以連接到一個或多個是一個用于檢查用戶提交的輸入是否合法的函數(shù)。表單域構(gòu)造函數(shù)的第一個參數(shù)是一個,在渲染表單到時(shí)會使用。驗(yàn)證確保提交的表單域不為空。表單域驗(yàn)證都是直接從包中導(dǎo)入。表格展示了一組支持的標(biāo)準(zhǔn)表單域。 第二章中介紹的request對象公開了所有客戶端發(fā)送的請求信息。特別是request.form可以訪問POST請求提交的表單數(shù)據(jù)。 盡管Flask的request...
摘要:注對于開發(fā)者來說,傳給應(yīng)用程序構(gòu)造函數(shù)的參數(shù)是比較容易弄混淆的。在應(yīng)程序中定義路由的最便捷的方式是通過顯示定義在應(yīng)用程序?qū)嵗系难b飾器,注冊被裝飾的函數(shù)來作為一個路由。一個常見的模式是使用裝飾器來注冊函數(shù)作為一個事件處理程序。 在這一章,你將學(xué)習(xí)Flask應(yīng)用程序不同部分。同時(shí)你將編寫和運(yùn)行你的第一個Flask web應(yīng)用程序。 1、初始化 在這章,你將學(xué)到Flask應(yīng)用程序的不...
摘要:他和妻子四個孩子兩只狗和一只貓共同生活在俄勒岡州波特蘭市。。還邀請他根據(jù)書的內(nèi)容,制作了兩個視頻教程。 showImg(http://img4.douban.com/lpic/s27205547.jpg); 這本書算是學(xué)習(xí)Flask的權(quán)威材料了,網(wǎng)上很多人都是推薦從這本書開始學(xué)習(xí)。起初,作者在自己的博客發(fā)布了一個大型的Flask建站教程,在這個教程大受歡迎的基礎(chǔ)上,才與OReilly公...
摘要:單元測試這個應(yīng)用非常小以至于不需要太多的測試,但是作為示例會在示例中展示兩個簡單的測試定義。示例單元測試編寫好的測試使用的是來自于標(biāo)準(zhǔn)庫中標(biāo)準(zhǔn)的包。為了運(yùn)行單元測試,可以在腳本中增加一個自定義的命令。 4、啟動腳本 頂層目錄中的manage.py文件用于啟動應(yīng)用。這個腳本會在示例7-8中展示。 示例7-8. manage.py:啟動腳本 #!/usr/bin/env python im...
摘要:用真實(shí)的值替換變量并返回最終響應(yīng)字符串,這個過程稱為渲染。示例展示模板實(shí)現(xiàn)該響應(yīng)??刂平Y(jié)構(gòu)提供一些控制結(jié)構(gòu)用于改變模板流。這個示例展示如何使用循環(huán)做到這些同樣支持宏,這和代碼中的函數(shù)很像。 寫代碼最關(guān)鍵的是要易于維護(hù)且結(jié)構(gòu)清晰整潔。目前為止,你看到的例子都過于簡單從而沒有做這方面的要求。Flask視圖函數(shù)希望將兩個應(yīng)該完全獨(dú)立的任務(wù)一并處理,兩個任務(wù)有兩種代碼,一并處理勢必會引發(fā)問題。...
閱讀 853·2019-08-30 15:54
閱讀 3321·2019-08-29 15:33
閱讀 2707·2019-08-29 13:48
閱讀 1222·2019-08-26 18:26
閱讀 3338·2019-08-26 13:55
閱讀 1488·2019-08-26 10:45
閱讀 1173·2019-08-26 10:19
閱讀 311·2019-08-26 10:16