Rails项目使用Postgres执行数据库迁移出现关联报错如何解决
问题原因
Rails 的数据库迁移是严格按照迁移文件名前缀的时间戳从小到大顺序执行的,从报错日志可以看出:
- 已执行的迁移顺序是先跑
20211001092658 CreateDevelopers,接下来要跑20211001093122 CreateMessages - 你创建
teams表的迁移文件时间戳一定晚于20211001093122,导致执行messages表的创建逻辑时,它依赖的teams表还未创建。加上你在messages表中加了t.references :team, null: false, foreign_key: true的外键约束,数据库会校验关联表是否存在,就抛出了relation "teams" does not exist的错误。
解决方案
根据你的场景选择对应操作即可:
场景1:本地开发、迁移未提交到远程仓库
这是最常见的场景,直接调整迁移文件的时间戳保证执行顺序符合依赖逻辑即可:
- 调整三个迁移的时间戳,保证顺序为:
CreateDevelopers<CreateTeams<CreateMessages
举个例子:
给CreateTeams的迁移文件名前缀改成20211001092900,介于开发者和消息表的时间戳之间即可 - 先回滚已经执行成功的开发者表迁移,执行命令:
rails db:rollback STEP=1 - 重新执行迁移即可:
rails db:migrate
场景2:迁移已提交到远程仓库、其他同事已经执行过
不要修改已提交的旧迁移的时间戳,避免造成团队内迁移状态混乱:
- 生成一个新的迁移文件用来创建
messages表,新迁移的时间戳自然晚于teams表的时间戳 - 如果之前的
CreateMessages迁移已经被部分人执行过,也可以单独写一个迁移来添加team外键关联,保证外键添加逻辑在teams表创建之后执行即可
可选优化建议
你当前teams表中用数组类型的dev_ids字段存储关联的开发者ID,不符合ActiveRecord的默认关联规范,后续操作关联数据会比较麻烦,推荐用中间表实现teams和developers的多对多关联,更适配Rails的生态操作。
内容的提问来源于stack exchange,提问作者Lazlo
相关产品推荐
相关产品推荐

