我需要对正在使用的生产数据库进行更改.只需添加几列.我已经通过迁移对dev数据库进行了更改.在保留现有数据的同时更新生产数据库并且不会过多地中断操作的最佳方法是什么?
它是MYSQL,我将需要向列添加数据以及已有的记录.一列可以有一个默认值(它是布尔值),但另一列是时间戳,应该有一个任意的后退值.行数并不大.
因此,如果我使用迁移,我如何添加数据?如何才能实现这两个(或三个 - 我在生成数据库上添加数据时最多的迁移,而不是最初是通过迁移构建的(我相信他们使用了架构而不是)?
我总是遵循这个程序:
使用mysqldump命令转储prod数据库
使用mysql命令使用dump填充dev/test数据库
在dev/test中运行迁移
检查迁移工作
使用mysqldump命令转储prod数据库(因为它可能已更改)在服务器上保留备份
在prod上运行迁移(使用capristano)
测试迁移对产品起作用
喝啤酒(边看错误日志)
听起来你处于这样一种状态:生产数据库模式与你在开发中使用的模式不完全匹配(虽然它并不完全清楚).我会在沙子中划一条线,让那个prod db处于更好的状态.基本上你要做的是确保prod db有一个"schema_info"表,列出你<不想在生产中运行的任何迁移.然后,您可以将迁移添加到您的内容中,它们将对生产数据库起作用.
完成后,您可以编写添加架构更改或添加数据的迁移,但您需要特别注意的一件事是,如果使用迁移添加数据,则必须在迁移本身内定义模型,如下所示:
class AddSomeColumnsToUserTable < ActiveRecord::Migration class User < ActiveRecord::Base; end def self.up add_column :users, :super_cool, :boolean, :default => :false u = User.find_by_login('cameron') u.super_cool = true u.save end def self.down remove_column :users, :super_cool end end
这样做的原因是,在将来,您可能会在某些重构或其他过程中完全删除模型.如果您没有在"User.find_by_login ..."行上定义用户类,则迁移将抛出异常,这是一个很大的痛苦.