弄完底層資料庫操作模塊後,接下來要做的是ORM的正式設計。在開始之前,我們需要思考一下怎麼來設計一個ORM呢?這個類它能幫助我們處理什麼樣的問題?需要有哪些功能模塊?怎麼做到針對不同的資料庫與表單進行操作? 在前面我們知道,ORM它簡單的理解就是將我們寫的一些參數值轉變為對應的sql語句,來對數據表 ...
弄完底層資料庫操作模塊後,接下來要做的是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 作者博客:http://www.cnblogs.com/EmptyFS/