一、说明
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__()方法肯定获取不到主键值----更准确点说是会报错。