Ecto约束调试Skill ecto-constraint-debug

此技能专用于调试Ecto ORM框架中的数据库约束违规问题,提供系统化的方法来诊断和解决唯一约束、外键约束和检查约束错误。通过解析错误、检查迁移、追踪插入路径和识别并发问题,帮助开发人员快速定位和修复数据库相关问题。适用于后端开发,关键词包括Ecto调试、约束错误、数据库约束、唯一索引、外键约束、并发控制、迁移检查。

后端开发 0 次安装 0 次浏览 更新于 3/11/2026

name: ecto-constraint-debug description: 调试Ecto约束违规 - 追踪触发器、检查迁移、查找重复数据。当看到unique_constraint、foreign_key_constraint或check_constraint错误时使用。

Ecto约束调试

诊断约束违规的系统化方法。当你看到Ecto.ConstraintErrorunique_constraintforeign_key_constraint或与约束相关的changeset错误时加载。

铁律

  1. 阅读约束名称 — 约束名称(例如,links_url_index)确切告诉你哪个索引/约束失败。首先从错误消息中解析它
  2. 先检查迁移再检查代码 — 验证priv/repo/migrations/中的约束定义是否与模式期望匹配
  3. 追踪所有插入路径 — 找到所有插入到约束表的代码路径。错误通常在你未考虑的路径中
  4. 假定为竞争条件直到证明其他原因 — 如果验证通过但约束失败,假定并发插入直到你证明单请求原因

逐步调试

步骤1: 解析错误

从错误消息中提取:

  • 约束名称(例如,users_email_index
  • 表名称(例如,users
  • 操作(插入、更新或删除)
  • 冲突值(如果日志中可用)

步骤2: 查找迁移

grep -r "constraint_name" priv/repo/migrations/
# 同时检查:create unique_index, create index, add constraint

验证:迁移约束是否匹配模式的unique_constraint/3foreign_key_constraint/3调用?

步骤3: 查找模式

# 在changeset中查找约束处理
grep -r "unique_constraint\|foreign_key_constraint\|check_constraint" lib/

步骤4: 追踪插入路径

查找所有插入/更新此模式的调用者:

grep -r "Repo.insert\|Repo.update\|Repo.insert_all\|cast_assoc.*:schema_name" lib/

步骤5: 识别原因

症状 可能原因 修复模式
同一用户触发两次 竞争条件(双击、重试) 使用on_conflict进行upsert
多个父级共享子级 cast_assoc不会在changesets间去重 在构建changesets前去重
并发API请求 缺少事务隔离 包装在Repo.transaction中或使用upsert
迁移为现有数据添加约束 数据违反新约束 首先回填或清理数据

步骤6: 应用修复

查看references/constraint-patterns.md获取详细修复模式。

按约束类型的快速修复

唯一约束违规 → Upsert: Repo.insert(changeset, on_conflict: :replace_all, conflict_target: [:field])

外键约束违规 → 检查:引用的记录是否存在?是否被并发删除?

检查约束 → 验证:值是否满足约束条件?

参考资料

  • references/constraint-patterns.md - 每种约束类型的详细模式