ORM反射資料表到實體類 好用到哭泣

2021-10-21 02:23:44 字數 2136 閱讀 5233

為了避免sql注入或白盒漏洞問題,同時也是為了方便資料底層操作,工作中會盡量避免使用原生sql,而選擇orm。python中常用的有sqlalchemy庫。該庫的使用可以學習參考

在使用過程中會發現需要自行建立乙個class去對映資料表結構,然後通過操作class進行資料的增刪改查等一系列操作。這個其實已經能滿足日常的使用,但是在工作中我們常會選擇資料分離,分工明確, 比如我就遇到需要設計底層dal,提供統一的資料介面給所有業務,我們可以選擇讓業務線把設計好的表結構或者建立語句統一給我們,然後儲存乙個py檔案去維護這些表資訊,將表結構對映成model。

這種做法有以下幾個問題:

修改表結構資訊,需要動態修改py檔案

業務線修改表結構可能不能完全同步到dal層,導致業務邏輯出現癱瘓

對於線上環境,每次修改都需要重新部署上線,這是乙個浪費人力和時間的事情,而且不能保證完全不出錯。

基於以上考慮,我們會考慮,如何動態獲取資料庫中表結構的變化,這就是所謂的資料表反射成實體類(起初不知道這個概念,只能查詢資料:如何動態生成資料表的model類)。

查詢資料,首先看到的是使用sqlacodegen方法,建議參考部落格:起初使用這種方法在本地確實可以方便的生成所有實體類,並生成model檔案,然後獲取檔案中的所有class,最後我們就可以通過表名獲取到對應的實體類,然後進行orm操作

def get_classes(module_name=storage.db_models) -> dict:

# 獲取db_models檔案 中所有類物件

classes =

table = {}

file = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/storage/' + 'db_models.py'

if not os.path.exists(file):

return table

ret = inspect.getmembers(module_name, inspect.isclass)

try:

for name, class_ in ret:

if '__tablename__' in dir(class_):

table[class_.__tablename__] = class_

except exception as e:

logging(e, exc_info=true)

return table

缺點:

通過ip+port的形式連線資料庫,在本地可操作,線上不一定會被允許,例如我們公司不允許使用ip+port的形式連線,封裝了自己的mysql庫,導致上線失敗

需要定時的去執行sqlacodegen命令,保證獲取的model檔案是最新的

強烈推薦使用這種方法

真是寶藏方法,解決了很大一麻煩,具體可以參考這篇部落格,裡面有三種方法 下面展示自己寫的偽**:親測是有效的,可以動態感知資料表結構變化

def create_model(self):

"""反射資料表為實體類"""

engine = sqlalchemyengine()._engine # 建立資料庫引擎,可以根據具體情況操作,不用擔心線上線下環境影響,和普通連線資料庫建立引擎方法相同

base = automap_base()

base.prepare(engine, reflect=true)

base.classes.keys() # 獲取所有的物件名

return base.classes

def test():

table = self.create_table()

table_name = 'test_example『 # 資料庫表名

model = table[table_name]

ret = s.query(model).filter_by(**condition).update(data) # 進行orm操作

通過這次事件,以後即使不做dal層,只寫業務**,也會選擇這種方法,不會呆板地維護自己的model類了,雖然對於熟悉業務的個人來說改造比較方便成本不大,但是如果進行業務交接就很麻煩了,保持乙個原則:能動態感知的盡量使用動態方法感知,能少改動**的少改動,能不重新上線的不上線。

根據SQLServer資料表生成C 實體類

生成表的實體類工具,有助於減少 量,加快開發速度.第一副圖根據輸入的連線伺服器位址 使用者名稱 登入資料庫名 密碼連線到資料庫.如果錯誤則提示連線失敗.第二幅圖先取的當前資料庫所有的使用者建立的表 然後根據選中的表名取得資料庫中關於此表資訊的的系統表.然後將字段型別轉換為c 資料型別.並輸出的tex...

利用反射將資料讀入實體類

利用反射將資料讀入實體類 在實際開發中,我們經常需要從資料庫中讀取資料並賦值給實體類的相應屬性。比如 public role getroles int blogid if reader name dbnull.value if reader description dbnull.value read...

java通過實體類名稱獲取對應的資料表名稱

entity name x 指定的是實體名稱,不是表名,但是實體名稱會影響生成的表名 根據命名約定 表名可能也是 x了。如要明確指定表名需要附加乙個 table 如果想根據類名拿到註解裡面的name屬性,可以用反射來做 class cls class.forname com.papapa.x 或直接...