db:schema:load vs db:使用capistrano迁移

Ano*_*non 22 mysql database rake capistrano ruby-on-rails

我有一个rails应用程序,我正在移动到另一台服务器,我想我应该使用db:schema:load来创建mysql数据库,因为它是推荐的.我的问题是我正在使用capistrano进行部署,而它似乎默认为rake db:migrate.有没有办法改变这个或使用db:migrate的capistrano有充分理由?

And*_*ack 32

为什么要使用db:schema:load

我发现我自己的迁移最终会对数据进行一些改组(例如,假设我将first_name和last_name列组合成一个full_name列).一旦我做了这些,我就开始使用ActiveRecord筛选数据库记录,你的模型最终会对某些列做出假设.例如,我的"人员"表后来被赋予了一个"位置"列,用户可以对其进行排序.之前的迁移现在无法选择数据,因为"位置"列尚不存在.

如何更改Capistrano中的默认行为

总之,我认为deploy:cold 应该db:schema:load而不是db:migrate.我通过改变Capistrano在冷部署上执行的中间步骤解决了这个问题.对于Capistrano v2.5.9,库代码中的默认任务如下所示.

namespace :deploy do
  ...
  task :cold do
    update
    migrate  # This step performs `rake db:migrate`.
    start
  end
  ...
end
Run Code Online (Sandbox Code Playgroud)

deploy.rb按照以下方式覆盖了我的任务.

namespace :deploy do
  task :cold do       # Overriding the default deploy:cold
    update
    load_schema       # My own step, replacing migrations.
    start
  end

  task :load_schema, :roles => :app do
    run "cd #{current_path}; rake db:schema:load"
  end
end
Run Code Online (Sandbox Code Playgroud)


Jon*_*vin 10

爬上Andres Jaan Tack,Adam Spiers和Kamiel Wanrooij的肩膀,我已经建立了以下任务来覆盖部署:冷.

task :cold do
  transaction do
    update
    setup_db  #replacing migrate in original
    start
  end
end

task :setup_db, :roles => :app do
  raise RuntimeError.new('db:setup aborted!') unless Capistrano::CLI.ui.ask("About to `rake db:setup`. Are you sure to wipe the entire database (anything other than 'yes' aborts):") == 'yes'
  run "cd #{current_path}; bundle exec rake db:setup RAILS_ENV=#{rails_env}"
end
Run Code Online (Sandbox Code Playgroud)

我的改进是......

  • 将其包裹起来transaction do,以便Capistrano在中止后进行适当的回滚.
  • db:setup代替db:schema:load,因此,如果数据库不存在,它会加载模式之前创建.


Ada*_*ers 6

这是Andres Jaan Tack的一个很好的答案.我只是想补充几点意见.

首先,这是Andres deploy:load_schema任务的改进版本,其中包含警告,更重要的是使用bundle execRAILS_ENV确保正确设置环境:

namespace :deploy do
  desc 'Load DB schema - CAUTION: rewrites database!'
  task :load_schema, :roles => :app do
    run "cd #{current_path}; bundle exec rake db:schema:load RAILS_ENV=#{rails_env}"
  end
end
Run Code Online (Sandbox Code Playgroud)

我已提交功能请求,已deploy:load_schema在Capistrano中实施.在那个请求中,我注意到Capistrano讨论组已经讨论了" db:schema:loadvs. db:migrate"辩论,并且有些人不愿意将deploy:cold任务转换为使用db:schema:loadover db:migrate,因为如果无意中运行,前者会破坏整个数据库,而后者可能会无害地抱怨和保释.然而,db:schema:load从技术上讲,这是更好的方法,因此如果可以减轻意外数据丢失的风险,那么值得转换.

  • 添加`提高RuntimeError.new("load_schema中止!"),除非Capistrano的:: CLI.ui.ask("你务必要对整个数据库(而不是'是’以外的任何中止)")=="yes'`在任务的开始工作就像一个魅力!这样可以安全地进行补丁部署:冷也是如此. (4认同)