1. 程式人生 > >Python3+SQLAlchemy不使用字段名獲取主鍵值教程

Python3+SQLAlchemy不使用字段名獲取主鍵值教程

參數 環境 之前 str pre 兼容 name def 一是

一、說明

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__()方法肯定獲取不到主鍵值----更準確點說是會報錯。

Python3+SQLAlchemy不使用字段名獲取主鍵值教程