一、說明
1.1 環境說明
user model如下,且其現有一個實例user_inst:
class User(Base): __tablename__ = 'users' username = Column(String(32), primary_key=True) passwd = Column(String(32)) def __repr__(self): return f"<User(username={self.username}, passwd={self.passwd}>"
event model,且其現有一個實例event_inst:
class Event(Base): __tablename__ = 'events' id = Column(Integer, primary_key=True) username = Column(String(32)) event_type = Column(String(32)) def __repr__(self): return f"<User(username={self.username}, event_type={self.event_type}>"
1.2 需求說明
現在代碼某處需要獲取實例的主鍵的值,且希望代碼能同時兼容不同model。
在不考慮兼容的情況下,要獲取實例主鍵值,分別寫如下即可:
user_inst.username
even_inst.id
但顯然user model和event model主鍵名稱是不一樣的,這種通過硬編碼主鍵字段名的方式實現不了兼容的要求。
二、不使用字段名獲取主鍵值實現
我們先約定,將user model和event model統稱為model;將user_inst和event_inst統稱為model_inst。
所謂統稱在代碼上的實現方法一是直接賦值(如model=User),二是當參數傳過去。
2.1 不使用字段名獲取主鍵值實現
from sqlalchemy import inspect # 獲取主鍵字段名。主鍵可能有多個,這里只取第一個 primary_key_name = inspect(self.sub_dao_class).primary_key[0].name # 通過__getattribute__獲取字段名對應的值 model_inst.__getattribute__(key)
2.2 注意未賦值情況
對於2.1中的方法,如果user_inst和event_inst都是從數據表中查詢出來的實例那是沒問題的。
如果不是從表中查出而是新定義的實例,user_inst也是沒問題的,但event_inst會有問題。
event model中的id是系統自增長的值,在實例化時我們一般不對其進行初始化,而是在插入數據庫時由數據庫確定。也就是說如果event_inst是新定義的那么在插入數據庫之前其主鍵(也即id字段)是沒有值的,此時通過__getattribute__()方法肯定獲取不到主鍵值----更准確點說是會報錯。