Peewee查询结果中外键属性自动追加_id后缀的原因及配置疑问
Peewee查询结果中外键属性自动追加_id后缀的原因及配置疑问
这其实是Peewee框架默认的外键字段映射机制,完全是设计预期的特性,不是bug哦~我来给你把背后的逻辑和调整方式说清楚:
1. 为什么会自动出现_id后缀的属性?
当你定义ForeignKeyField的时候,比如ProcessedImage里的image_id = ForeignKeyField(Image, ...),Peewee默认会做两层映射:
- 把
row.image_id映射为关联的Image模型实例(也就是你看到的Image行数据),方便你直接操作关联对象——比如不用额外查询就能拿到row.image_id.filename; - 把数据库里存储的原始外键ID数值,放在
row.image_id_id这个属性里——这个后缀是框架自动加的,用来明确区分“关联对象”和“原始ID值”。
这个设计的核心是为了提升开发效率,让你不用手动写关联查询就能直接访问关联数据。
2. 关于lazy_load参数的影响
你提到设置lazy_load=False后,row.image_id和row.image_id_id都变成了实际字段值,这是因为关闭懒加载后,Peewee不会自动去查询并实例化关联的Image对象,直接返回数据库里的原始ID值。框架保留_id后缀的属性是为了兼容之前的代码,所以两个属性会指向同一个值。
3. 怎么调整属性命名,达到你想要的反向效果?
你说设置object_id_name='ref_image_id'后,row.image_id是Image对象、row.ref_image_id是ID值,这确实是object_id_name的作用:它用来指定存储原始外键ID的属性名,而外键字段本身的名称则用来映射关联对象。
如果你想反过来——让row.image_id直接是ID值,用另一个属性名(比如row.image)存储关联对象——可以调整外键的定义方式:
class ProcessedImage(MAFwBaseModel): # 用`image`作为关联对象的属性名,指定db_column对应数据库的image_id列 image = ForeignKeyField( Image, primary_key=True, backref='+', help_text='关联的Image对象', on_delete='CASCADE', db_column='image_id' # 对应数据库表中的实际列名 ) value = FloatField(default=0)
这样定义后:
row.image会是关联的Image模型实例;row.image_id会是数据库里存储的原始外键ID值,完全符合你想要的命名逻辑。
最后补充
这个行为和你用的是交叉连接还是其他查询无关,只要是Peewee的外键字段,默认都会遵循这个映射规则。
备注:内容来源于stack exchange,提问作者toto
相关产品推荐
相关产品推荐

