- Python高效開發實戰:Django、Tornado、Flask、Twisted(第3版)
- 劉長龍
- 2343字
- 2021-10-15 17:52:58
4.3 ORM編程
除了直接用SQL語句操作關系數據庫,Python中的另一種與關系數據庫進行交互的技術是ORM。本節介紹ORM的概念和Python中的ORM包。
4.3.1 ORM理論基礎
ORM(Object-Relational Mapping,對象關系映射)的作用是在關系數據庫和業務實體對象之間做一個映射,這樣開發者在操作數據庫中的數據時,就不需要再去和復雜的SQL語句打交道,只需簡單地操作對象的屬性和方法即可。所有的ORM必須具備3方面的基本能力:映射技術、CRUD操作和緩存優化。
1. 映射技術
面向對象是從軟件工程的基本原則(如耦合、聚合、封裝)的基礎上發展而來的,而關系數據庫是從數學理論的基礎上發展而來的,兩套理論存在顯著的區別,ORM通過映射機制將兩種技術聯系起來。每種編程語言都有自己的ORM庫,例如,Java的Hibernate、iBATIS,C#的Grove、LINQ,Python的SQLAlchemy等,所有這些ORM庫都必須解決如下3個映射問題。
? 數據類型映射:將數據庫的類型映射為編程語言自身的類型。數據類型映射解決了由數據表列(Column)類型向編程語言類型轉換的問題。例如,SQLAlchemy中定義了一系列的數據類型(SmallInteger、Float、Time等)用于對應數據庫中的類型。
? 類映射:將數據表定義映射為編程語言自身的類,這樣數據表中的每一條記錄就可以映射為一個編程語言自身的對象。因為數據表的定義本身在每個業務場景中各不一樣,所以需要開發者通過配置文件或代碼文件的方式明確類映射。在SQLAlchemy中開發者通過定義繼承自declarative_base()返回的類型來實現類映射。
? 關系映射:將數據庫中基于外鍵的關系連接轉換為編程語言中基于對象引用的關系連接。在SQLAlchemy中通過在數據表類中定義relationship()字段,使開發者能夠指定數據表之間的連接關系。
2. CRUD操作
CRUD是做數據庫處理時的增加(Create)、讀取(Retrieve,重新得到數據)、更新(Update)和刪除(Delete)幾個單詞的首字母組合。在SQL中通過INSERT、SELECT、UPDATE、DELETE四種語句實現CRUD。而由于ORM對開發者屏蔽了SQL,因此所有的ORM庫必須提供自己的一套CRUD方案。
大多數庫會為數據對象提供insert、update、delete、query等函數實現CRUD,并提供beginTransaction、commit、rollback等函數管理事務。當開發者調用這些函數時,ORM自動執行下列操作。
? 將這些調用轉換為SQL語句。
? 通過數據庫引擎發送給數據庫執行。
? 將數據庫返回的結果記錄用ORM映射技術轉換為類對象。
3. 緩存優化
由于數據庫操作通常比較耗時,因此大多數ORM提供數據緩存優化的功能,最基本的緩存優化功能如下。
? 將從數據庫中查詢到的數據以類對象的形式保存在內存中,以便之后再用時隨時提取。
? 在真正需要讀取查詢結果時才執行數據庫的SELECT操作,而不是在ORM查詢命令執行時查詢數據庫。
4. 為什么使用ORM
在學習了ORM的基本原理后,我們總結ORM的優點如下。
? 向開發者屏蔽了數據庫的細節,使開發者無須與SQL語句打交道,提高了開發效率。
? 便于數據庫遷移。由于每種數據庫的SQL語法有細微差別,因此基于SQL的數據訪問層在更換數據庫時通常需要花費大量的時間調試SQL語句。而ORM提供了獨立于SQL的接口,ORM引擎會處理不同數據庫之間的差異,所以遷移數據庫時無須更改代碼。
? 應用緩存優化等技術有時可以提高數據庫操作的效率。
4.3.2 Python ORM庫介紹
ORM在開發者和數據庫之間建立了一個中間層,把數據庫中的數據轉換成了Python中的對象實體,這樣既屏蔽了不同數據庫之間的差異性,又使開發者可以非常方便地操作數據庫中的數據,而且可以使用面向對象的高級特性。
Python中提供ORM支持的組件有很多,每個組件的應用領域稍有區別,但是數據庫操作的理論原理是相同的。對比較著名的Python數據庫的ORM框架介紹如下。
? SQLAlchemy:Python中最成熟的ORM框架,資源和文檔都很豐富。大多數Python Web框架對其都有很好的支持,能夠勝任大多數應用場合。SQLAlchemy被認為是Python事實上的ORM標準。
? Django ORM:Python世界中大名鼎鼎的Django Web框架獨用的ORM技術。Django是一個大而全的框架,這使得其靈活性大大降低。其他Python Web框架可以隨意更換ORM,但在Django中不能這樣做,因為Django內置的很多model是用Django內置ORM實現的。
? Peewee:小巧靈活,是一個輕量級ORM。Peewee是基于SQLAlchemy內核開發的,整個框架由一個文件構成。Peewee提供了對多種數據庫的訪問方式,如SQLite、MySQL、PostgreSQL,適用于功能簡單的小型網站。
? Storm:一個中型的ORM庫,比SQLAlchemy和Django等輕量,比Peewee的功能更豐富。Storm要求開發者編寫數據表的DDL代碼,而不能直接從數據表類定義中自動生成表定義。
? SQLObject:與SQLAlchemy相似,也是一套大而全的ORM。SQLObject的特點是它的設計借鑒了Ruby on Rails的ActiveRecord模型,使得熟悉Ruby的開發者非常容易上手。
4.3.3 實戰演練:Peewee庫編程
本書中篇的Django框架和Flask框架部分將會詳細介紹Django ORM和SQLAlchemy的使用方法,此處對輕量級框架Peewee的使用方法進行介紹,以便讀者能夠迅速掌握ORM的編程思路。
注意:在實踐Peewee之前需要先通過pip install peewee命令安裝該組件。
由于在一般情況下ORM庫自身的緩存優化機制可以滿足大多數場景的需要,因此使用ORM的編程通常由兩部分組成:定義數據表到Python ORM類的映射關系;連接數據庫并進行CRUD等操作。
【示例4-2】以表4.1和表4.2定義的course和teacher數據表為例,用Peewee定義Python ORM類的示例代碼如下:


對本示例代碼的解析如下。
? 首先引入了Peewee包。
? 用SqliteDatabase()類定義了SQLite的數據庫實例。對于其他數據庫類型,可以使用相似的MySQLDatabase()及PostgresqlDatabase()等。
? 定義了ORM基類BaseModel,在其中指定了公用的屬性database值為之前建立的SQLite連接。
? 類型映射,Peewee中預定義了一系列的數據類型,用于定義數據表中的列,在本例中用到了PrimaryKeyField(主鍵)、CharField(字符串)、IntegerField(整型)、BooleanField(布爾型)等。
? 表映射:定義了兩個對象類Course和Teacher,用于映射數據表course和teacher,注意在每個類的Meta中設置了數據庫中該類對應的真實表名。
? 關系映射:在Teacher中通過ForeignKeyField設置了其與Course的連接關系,ForeignKeyField的參數to_field用于指定被連接的字段名,related_name參數為該關系賦予了一個名字。
? 用CLASSNAME.create_table()自動在數據庫中建立符合該類定義的數據表。
【示例4-3】下面的代碼演示了使用如上ORM映射對數據內容進行增、刪、改、查的方法:

在該段代碼中分別演示了新建表、增加新記錄、查詢單行、更新單個記錄對象、刪除單條對象,以及一些復雜的查詢、更新技巧。
現在嘗試運行【示例4-2】與【示例4-3】,得到的結果如下:

讀者可逐條對比代碼與上述結果。
- 神經網絡編程實戰:Java語言實現(原書第2版)
- Web Application Development with R Using Shiny(Second Edition)
- 編寫高質量代碼:改善C程序代碼的125個建議
- Learning ArcGIS Pro
- Visual Basic程序設計習題解答與上機指導
- JS全書:JavaScript Web前端開發指南
- Unity 5.x By Example
- 琢石成器:Windows環境下32位匯編語言程序設計
- Machine Learning in Java
- Android開發三劍客:UML、模式與測試
- Mastering Web Application Development with AngularJS
- Python商務數據分析(微課版)
- Machine Learning for OpenCV
- 算法秘籍
- WordPress Search Engine Optimization(Second Edition)