我需要对正在使用的生产数据库进行更改。只需添加几列。我已经通过迁移对dev数据库进行了更改。在保留现有数据的同时更新生产数据库并且不会过多地中断操作的最佳方法是什么?
这是MYSQL,我需要将数据添加到列以及已有的记录。一列可以有一个默认值(它是布尔值),但另一列是时间戳,应该有一个任意的后退值。行数不是很大。
因此,如果我使用迁移,我如何添加数据?我如何才能实现这两个(或三个 - 我在生成数据库上添加数据时最多的迁移,而不是最初通过迁移构建的)(我相信他们使用架构代替)?
答案 0 :(得分:14)
我总是遵循这个程序:
答案 1 :(得分:6)
听起来你处于这样一种状态,即生产数据库模式与你在开发中使用的模式不完全匹配(虽然它并不完全清楚)。我会在沙子中划一条线,让那个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 ...”行上定义用户类,那么迁移将抛出异常,这是一个很大的痛苦。
答案 2 :(得分:4)
您是否有理由不使用在开发环境中使用的相同迁移?
答案 3 :(得分:2)
在迁移中添加add_column
的列应该是非破坏性的:它将生成“ALTER TABLE”语句。如果您知道在创建后将要放入列中的内容,则可以在迁移中填写值(如果行数很大,您可以选择耗时较少的替代值)。
我认为删除或更改列的定义取决于平台:有些将允许删除列,其他人将执行rename-create-select-drop命令序列。
为了更具体,我们需要更多信息:您正在查看哪种迁移,您运行的是哪个平台,是否需要在迁移过程中设置值?这样的东西会有很多帮助 - 只需编辑问题,这会将其推回到列表中。