弄完底層數據庫操做模塊後,接下來要作的是ORM的正式設計。在開始以前,咱們須要思考一下怎麼來設計一個ORM呢?這個類它能幫助咱們處理什麼樣的問題?須要有哪些功能模塊?怎麼作到針對不一樣的數據庫與表單進行操做?python
在前面咱們知道,ORM它簡單的理解就是將咱們寫的一些參數值轉變爲對應的sql語句,來對數據表進行增刪改查的操做。它能夠幫助咱們整合重複的代碼,讓咱們對數據庫操做變的更加簡單。也就是說,只須要將參數存儲到對應的字典、列表或元組中,並將它們作爲參數提交給ORM,ORM就會自動分析並處理,而後生成對應的sql語句。對於Pythoner來講,字典、列表和元組是咱們最熟悉的變量,操做它們會更加的熟悉,而不是sql語句。sql
那麼ORM應該擁有哪些功能模塊?咱們能夠從對數據庫操做的角度進行思考,咱們對數據庫的操做無非就是增刪改查,那麼分解下來,實際上就是咱們所要實現的功能了。好比說:新增記錄、修改記錄、刪除記錄、按指定條件查詢、查詢指定主鍵記錄、判斷記錄是否存在、查詢數量統計、查詢指定值合計數、獲取指定字段最大值、獲取指定字段最小值......能夠看到咱們經常使用的查詢仍是挺多的,只要將它們一一實現,那麼之後操做起這些功能就會變得更加的簡單方便。數據庫
而對於有多數據庫時,咱們只須要將ORM進行抽象建立一個ORM基類,全部的數據表操做類繼承它(每一個數據表咱們都須要獨立建立一個對應的類,它須要繼承ORM基類來獲取基類的全部能力),在實例化數據表操做類時,像上一章所講到的那樣經過參數注入方式處理,即不一樣的數據庫咱們注入不一樣的數據庫鏈接配置,這樣咱們在實例化數據表操做類時,就沒必要考慮它究竟是屬於那個數據庫,咱們只須要知道每一個表對於每一個數據庫來講都是惟一的,在實例化時該操做類就會進行初始化操做,而後自動載入對應的數據庫配置,當對這個表進行操做時,它也會自動鏈接對應的數據庫執行相關的操做了。(以下圖)測試
根據上面的理解,咱們先建立一個ORM基類:_logic_base.py(也能夠稱爲邏輯層父類)spa
#!/usr/bin/env python # coding=utf-8 from common import db_helper class LogicBase(): """邏輯層基礎類""" def __init__(self, db, is_output_sql, table_name, column_name_list='*', pk_name='id'): """類初始化""" # 數據庫參數 self.__db = db # 是否輸出執行的Sql語句到日誌中,方便分析 self.__is_output_sql = is_output_sql # 表名稱 self.__table_name = str(table_name).lower() # 查詢的列字段名稱,*表示查詢所有字段,多於1個字段時用逗號進行分隔,除了字段名外,也能夠是表達式 self.__column_name_list = str(column_name_list).lower() # 主健名稱 self.__pk_name = str(pk_name).lower()
子類在繼承該類時,經過對__init__()進行初始化,將相關的參數注入進來,在後續執行相關操做時,就能夠直接調用這些參數進行設置了。例如咱們建立一個manager表對應的操做類ManagerLogic():設計
1 #!/usr/bin/env python 2 # coding=utf-8 3 4 from logic import _logic_base 5 from config import db_config 6 7 8 class ManagerLogic(_logic_base.LogicBase): 9 """用戶管理表邏輯類""" 10 11 def __init__(self): 12 # 表名稱 13 __table_name = 'manager' 14 # 初始化 15 _logic_base.LogicBase.__init__(self, db_config.DB, db_config.IS_OUTPUT_SQL, __table_name)
經過from logic import _logic_base來導入父類,被ManagerLogic類所繼承。日誌
而後導入數據庫配置文件db_config。code
ManagerLogic類在執行__init__()初始化時,在第15行中綁定好該類對應的數據庫(不一樣類能夠綁定不一樣的配置文件,即不一樣的數據庫),設置好IS_OUTPUT_SQL參數(是否輸出全部執行的Sql語句到日誌中,用於開發人員分析),以及設置該類綁定的數據表名稱(經過這裏綁定,在後續操做時就不會由於複製粘貼時不小時弄錯表名了,固然在建立數據表子類時也要當心不要綁錯表名稱了)。blog
column_name_list是用於查詢時,若是不設置輸出字段名,則會默認使用這個變量作爲參數,方便有些表在操做時能夠直接在這裏設置好輸出字段名的限制。默認值爲*,表示輸出全部字段內容。繼承
pk_name是數據表的主鍵名稱,默認爲id,對於一些不以id爲默認值的,能夠在這裏進行設置爲該表指定的主鍵名稱。
作好這些,ManagerLogic類就擁有了父類全部的能力(方法)了——固然須要後面將父類的功能實現後才行。
好比父類擁有get_model()方法
def get_model(self): """經過條件獲取一條記錄""" return '獲取一條記錄'
那麼咱們能夠寫個測試用例,經過下面方式來進行調用
#!/usr/bin/evn python # coding=utf-8 import unittest from logic import manager_logic class DbHelperTest(unittest.TestCase): """數據庫操做包測試類""" def setUp(self): """初始化測試環境""" print('------ini------') def tearDown(self): """清理測試環境""" print('------clear------') def test(self): ############################################## # 只須要看這裏,其餘代碼是測試用例的模板代碼 # ############################################## # 實例化manager表操做類ManagerLogic _manager_logic = manager_logic.ManagerLogic() # 執行get_model()方法,獲取記錄實體 model = _manager_logic.get_model() print(model) ############################################## if __name__ == '__main__': unittest.main()
輸出結果:
------ini------
獲取一條記錄
------clear------
看起來是否是很簡單。
版權聲明:本文原創發表於 博客園,做者爲 AllEmpty 本文歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然視爲侵權。
python開發QQ羣:669058475(本羣已滿)、733466321(能夠加2羣) 做者博客:http://www.cnblogs.com/EmptyFS/