弄完底層數據庫操作模塊后,接下來要做的是ORM的正式設計。在開始之前,我們需要思考一下怎么來設計一個ORM呢?這個類它能幫助我們處理什么樣的問題?需要有哪些功能模塊?怎么做到針對不同的數據庫與表單進行操作?
在前面我們知道,ORM它簡單的理解就是將我們寫的一些參數值轉變為對應的sql語句,來對數據表進行增刪改查的操作。它可以幫助我們整合重復的代碼,讓我們對數據庫操作變的更加簡單。也就是說,只需要將參數存儲到對應的字典、列表或元組中,並將它們做為參數提交給ORM,ORM就會自動分析並處理,然后生成對應的sql語句。對於Pythoner來說,字典、列表和元組是我們最熟悉的變量,操作它們會更加的熟悉,而不是sql語句。
那么ORM應該擁有哪些功能模塊?我們可以從對數據庫操作的角度進行思考,我們對數據庫的操作無非就是增刪改查,那么分解下來,實際上就是我們所要實現的功能了。比如說:新增記錄、修改記錄、刪除記錄、按指定條件查詢、查詢指定主鍵記錄、判斷記錄是否存在、查詢數量統計、查詢指定值合計數、獲取指定字段最大值、獲取指定字段最小值......可以看到我們常用的查詢還是挺多的,只要將它們一一實現,那么以后操作起這些功能就會變得更加的簡單方便。
而對於有多數據庫時,我們只需要將ORM進行抽象創建一個ORM基類,所有的數據表操作類繼承它(每個數據表我們都需要獨立創建一個對應的類,它需要繼承ORM基類來獲取基類的所有能力),在實例化數據表操作類時,像上一章所講到的那樣通過參數注入方式處理,即不同的數據庫我們注入不同的數據庫連接配置,這樣我們在實例化數據表操作類時,就不必考慮它到底是屬於那個數據庫,我們只需要知道每個表對於每個數據庫來說都是唯一的,在實例化時該操作類就會進行初始化操作,然后自動載入對應的數據庫配置,當對這個表進行操作時,它也會自動連接對應的數據庫執行相關的操作了。(如下圖)
根據上面的理解,我們先創建一個ORM基類:_logic_base.py(也可以稱為邏輯層父類)
#!/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。
ManagerLogic類在執行__init__()初始化時,在第15行中綁定好該類對應的數據庫(不同類可以綁定不同的配置文件,即不同的數據庫),設置好IS_OUTPUT_SQL參數(是否輸出所有執行的Sql語句到日志中,用於開發人員分析),以及設置該類綁定的數據表名稱(通過這里綁定,在后續操作時就不會因為復制粘貼時不小時弄錯表名了,當然在創建數據表子類時也要小心不要綁錯表名稱了)。
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/