Peewee Model调用.dicts报错修正及保存失败记录信息获取方案
问题分析与修正方案
原代码错误原因与开发意图推测
- 原开发人员的核心意图是在
save执行失败时打印模型实例的全量字段信息,方便定位脏数据或逻辑错误 - 错误点:
dicts()是Peewee中BaseQuery查询集类的专属方法,作用是将查询返回的多条记录批量转为字典格式的可迭代对象,不能直接作用于单个Model实例,所以会触发AttributeError
三个核心问题解答
1. 如何从Model实例获取对应的BaseQuery?
仅当实例已经成功写入数据库、存在主键值时,才能构造对应单条记录的BaseQuery,写法如下:
# i为Model实例 single_record_query = type(i).select().where(type(i)._meta.primary_key == i.get_id())
2. 调用对应.dicts()会输出什么内容?
上述单记录查询调用.dicts()后会返回一个可迭代对象,遍历后得到长度为1的列表,元素为该记录的字段名与值组成的字典,示例输出:[{"id": 1, "dtfield": "2024-01-01 12:00:00", "intfield": 10, "floatfield": 1.2}]
3. 该信息是否适配告警场景的需求?
完全不适配,核心原因有两个:
- 大部分
save失败的场景都是新记录插入失败,此时实例还没有生成主键,根本无法构造上述BaseQuery查询 - 绕查询集拿字典属于冗余操作,完全没必要额外查询一次数据库,才能拿到内存中已经存在的实例字段值
最优修正方案
直接从内存中的Model实例获取字段字典即可,有两种成熟写法可选:
写法1:直接转dict(无额外导入,最简便)
将warning行替换为:
logger.warning("could not save record: {}, error info: {}".format(dict(i), str(e)))
写法2:用peewee官方提供的model_to_dict方法(支持关联模型序列化,复杂场景适用)
先导入工具方法:
from peewee import model_to_dict
再替换warning行:
logger.warning("could not save record: {}, error info: {}".format(model_to_dict(i), str(e)))
两种写法都可以正常输出实例的全量字段信息,完美匹配告警定位需求,插入、更新失败场景都可以正常使用。
修正后的完整store方法示例
def store(self): with self.db.atomic(): for i in self.records: try: i.save() except Exception as e: logger.warning("could not save record: {}, error info: {}".format(dict(i), str(e))) raise e self.clear()
内容的提问来源于stack exchange,提问作者Wör Du Schnaffzig
相关产品推荐
相关产品推荐

