企业 数据清洗

Odoo 企业版数据清洗为什么不是“查出重复记录再点合并”:master 选举、foreign key 回写与 merge log 讲透

基于 data_cleaning 源码,讲清重复记录为何要先算相似度、选主记录、回写外键和 followers,再决定删除还是归档。

企业 其他
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 4 阅读

“去重合并”经常被想象成一个很简单的按钮:选一条保留,剩下删掉。但 enterprise/data_cleaning/models/data_merge_group.pydata_merge_record.py 说明,真正的企业级合并需要回答四个难题:谁是主记录、哪些字段真的不同、所有外键怎么回写、合并后怎么留痕。

一、先算相似度,不是为了好看,而是为了告诉你差异在哪里

_compute_similarity() 会拿候选记录的相似字段做交集,算出 divergent_fieldssimilarity。这一步不是可视化装饰,而是在提醒操作者:这些记录虽然被判成一组,但并不代表它们完全一致。

这很关键,因为企业真实数据去重里,重复记录往往只有 70%~90% 相似。没有差异字段提示,用户很容易在错误前提下直接合并。

二、主记录选举不是拍脑袋,可以走模型自定义,也有默认规则

_elect_master_record() 会先看业务模型自己有没有 _elect_method();没有再走 group 的默认选举逻辑。这说明官方承认“谁该留下”并不是一个对所有模型都通用的规则。

比如联系人、线索、产品、员工,保留主记录的优先级都可能不同。企业项目里最危险的做法,就是用同一套“最后创建的保留”规则处理所有模型。

三、真正麻烦的是外键与附属对象回写

_update_foreign_keys() 会搜索所有引用目标表的关系字段,然后批量把 source 指向 destination;_merge_additional_models() 还会专门处理 ir_attachmentmail_activityir_model_datamail_message 等附属表;_merge_mail_followers() 则额外防止 follower 合并时触发唯一键冲突。

这才是企业去重与“手工删重复行”的本质差异:你合并的不是显示出来的两条记录,而是它们背后一整张引用网络。

四、合并之后还要决定原记录是删还是归档,并写日志

_post_merge() 会根据 removal_mode 和模型是否支持 active 字段,决定 unlink() 还是写 inactive。_log_merge() 则把被合并记录的快照和上下文发到 master record 的 chatter。

这两步共同回答了两个运维问题:

  • 原记录还能不能被追溯;
  • 后面谁来证明这次合并到底发生过什么。

没有日志的去重,在审计和排障场景里几乎等于没做。

实战注意事项

  1. 先看差异字段再点 merge:不要把“判成一组”误解成“完全相同”。
  2. 为关键模型定义 elect 规则:主记录选举不应只靠默认实现。
  3. 先理解引用网络:附件、活动、消息、followers 都可能跟着移动。
  4. 决定删除还是归档:审计要求高的模型通常更适合归档而不是硬删。

新手误区

  • 误以为去重就是删掉一条显示重复的数据。
  • 误以为 master 选谁都差不多。
  • 误以为外键回写只影响少数关系字段。
  • 误以为合并完成后不需要留痕。

主要源码参考

  • enterprise/data_cleaning/models/data_merge_group.py
  • enterprise/data_cleaning/models/data_merge_record.py

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。