【发布时间】:2009-04-15 04:26:15
【问题描述】:
我看到很多关于 ActiveRecord 迁移以及是否应该使用它们来更改应用程序中的数据的讨论,有些人说是,有些人说不。我的问题是,如果您不使用迁移来执行此操作,那么您使用的是什么?只是您编写的另一个脚本?
我正在寻求有关替代方法的建议,以及为什么它们可能比仅使用迁移更好。
【问题讨论】:
标签: ruby-on-rails ruby activerecord migration
我看到很多关于 ActiveRecord 迁移以及是否应该使用它们来更改应用程序中的数据的讨论,有些人说是,有些人说不。我的问题是,如果您不使用迁移来执行此操作,那么您使用的是什么?只是您编写的另一个脚本?
我正在寻求有关替代方法的建议,以及为什么它们可能比仅使用迁移更好。
【问题讨论】:
标签: ruby-on-rails ruby activerecord migration
如果你使用提供的,就会出现一个问题
rake db:reset
和
rake db:schema:load
任务,它使用schema.rb 作为设置数据库的基础。所以没有数据被加载并且你被卡住了。
在Agile Web Development with Rails, Third Edition,你应该得到(如果 Ruby 书是“Pickaxe”书,这应该是“Hammock”书,顺便说一句?)如果你还没有这样做,DHH 说:
...迁移并非真的意味着 携带种子数据。他们太临时了 在本质上可靠地做到这一点。 移民来这里把你从 架构的一个版本到下一个版本, 不要创建一个新的模式 从头开始——我们有 db/schema.rb 文件 为此。
所以,只要你真的 开始使用真正的应用程序, 人们不会早早跑你的 当他们设置迁移时 应用。他们将从 无论版本存储在 db/schema.rb 并忽略所有这些 以前的迁移。这意味着 迁移创建的任何数据 永远不要进入数据库,所以 你不能依赖它。
有很多 拥有更多的替代方法 永久种子数据。最简单的是 可能只是为了创建一个新文件 db/seed.rb,其中包含那些 Product.create 调用将执行 设置。然后可以调用此文件 在 rake db:schema:load 创建后 初始架构。
【讨论】:
rake db:reset 也运行 rake db:seed,因此种子文件中的所有数据都会随之加载。
很多时候,迁移是最合适的,不能用单独的脚本代替。想象以下场景:应用程序已经在使用实时数据; code 列包含“name-zip_code”形式的代码(是的,我知道它很丑,但它确实发生了),并且您希望将其分成两列,“name”和“zip_code”,同时摆脱 '代码”列。
def self.up
add_column :companies, :zip_code, :integer
add_column :companies, :name, :string
Company.reset_column_information
Company.find(:all).each do |company|
name, zip_code = company.code.split('-')
company.update_attributes(:name => name, :zip_code => zip_code)
end
remove_column :companies, :code
end
在这种情况下,在将数据传输到名称和邮政编码列之前,无法删除代码列。
【讨论】:
当我需要修改数据库中的一些数据时,我会创建一个运行一些库函数来完成工作的 Rake 任务。这样,数据操作将是可重复的,如果需要,也可以从迁移中运行。
【讨论】: