如何用PeeWee/Playhouse迁移工具实现数据规范化回写?
PeeWee迁移中数据规范化回写的解决方案
你遇到的问题是migrator.raw()仅会生成SQL语句对象,不会实际执行查询并返回数据。要完成数据规范化回写,需要直接通过数据库连接执行查询获取结果,同时注意避免SQL注入风险。
修正后的代码
def up(): # 执行SELECT查询获取去重字段值 cursor = migrator.database.execute_sql("SELECT DISTINCT column FROM table") # 提取查询结果中的字段值(row[0]对应查询的第一列,按需调整) raw_values = [row[0] for row in cursor.fetchall()] # 生成旧值到规范化新值的映射 value_mapping = {old_val: canonical(old_val) for old_val in raw_values} # 批量执行参数化更新 for old_val, new_val in value_mapping.items(): if old_val != new_val: # 跳过无需修改的条目 update_sql = "UPDATE table SET column = %s WHERE column = %s" migrator.database.execute_sql(update_sql, (new_val, old_val))
核心要点
- 获取实际查询结果:
migrator.database.execute_sql()会直接执行SQL并返回游标,通过fetchall()可以获取所有查询行,再提取你需要的字段值。 - 参数化查询防注入:绝对不要直接用字符串拼接生成UPDATE语句,改用占位符
%s并传入参数元组,PeeWee会自动适配不同数据库的语法要求,避免SQL注入风险。 - 优化更新操作:添加
old_val != new_val的判断,避免对无需修改的数据执行更新,减少数据库操作开销。
内容的提问来源于stack exchange,提问作者David Mertz
相关产品推荐
相关产品推荐

