Rails Migration 新增列并设置值,如何组织更新步骤?

xinyifly · 2019年05月27日 · 最后由 xinyifly 回复于 2019年05月27日 · 2071 次阅读

比如 migration 之前只有 posts 表,字段只有 body。

现在添加 users 表,并注册了一个 user。

然后想给 posts 表添加 user_id,全部更新为这个唯一的 user。

最终要在 db 层面去掉 default value 和 nullable。

更麻烦一点的场景:测试环境和生产环境这个 user 的 id 不一样。

怎么组织更新步骤?需要几个 migration?是否(何时)需要在 migration 之外手动更新数据表?

5 月 31 日更新

发现 rails migration 的 references 类型默认就是 nullable,非空检察由 rails 框架完成(belongs_to),不需要添加“在 db 层面去掉 default value 和 nullable”这一步。

这种不一致的数据迁移我会单独写一个脚本,migration 只管模式迁移。

我习惯一个迁移包含一个任务,顶楼情况,增加 user 表和添加 user_id 是一个任务(增加 User Model),去掉 default value 是另一个任务(这跟 User 有关吗?)。

1.新增一个 migration,用于 posts 表添加 user_id

2.新增一个 task,用于更新数据

总结来看,这样的一次发布会包含两个 migration 和一个数据更新。

post 不包含 user_id 的旧业务逻辑

  • migration 1:posts 添加 user_id (nullable, default null)(以及创建 users 表)
  • 执行更新脚本:把所有 posts 的 user_id 更新到一致状态

post 包含 user_id 的新业务逻辑

  • migration 2:posts 的 user_id 去掉 nullable 和 default null

执行更新脚本之前,到 post 包含 user_id 的新业务逻辑发布的这段时间,为了防止空 user_id 的新 post 产生,需要停机,我这样理解对吗?

xinyifly 回复

不需要停机。

  1. 先执行 migration 1,创建 users 表,添加 user_id 到 posts 表
  2. 在你的 rails 应用中增加一个逻辑:创建 post 时设置 user_id;
  3. 跑脚本,更新 posts 的 user_id
  4. 执行 migration 2

这个场景做到了兼容旧版数据库确实不需要停机

xinyifly 关闭了讨论。 05月27日 17:57
xinyifly 重新开启了讨论。 05月27日 17:59

感谢各位回复,了解了一下大家更新数据表的常规思路。

xinyifly 关闭了讨论。 05月27日 18:51
xinyifly 重新开启了讨论。 05月31日 17:18
xinyifly 关闭了讨论。 06月01日 09:35
需要 登录 后方可回复, 如果你还没有账号请 注册新账号