DB:架构:负载VS DB:与Capistrano的迁移(db:schema:load vs db:

2019-08-02 11:47发布

I have a rails app that I'm moving to another server and I figure I should use db:schema:load to create the mysql database because it's recommended. My problem is that I'm using capistrano to deploy and it seems to be defaulting to rake db:migrate instead. Is there a way to change this or is capistrano using db:migrate for a good reason?

Answer 1:

为什么要使用DB:架构:负载

我发现我自己的迁移,最终的数据做一些洗牌(假设我结合FIRST_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

我推翻了任务,我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


Answer 2:

在安德烈家安粘性,亚当尖塔和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

我在这里的改进是...

  • 敷在transaction do ,这样会Capistrano的中止后做一个适当的回滚。
  • db:setup ,而不是db:schema:load ,因此,如果数据库不存在,它将被载入架构之前创建的。


Answer 3:

这是一个从安德烈斯家安粘性很大的答案。 我只想补充几点看法。

首先,这里的安德烈的改进版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

我已经提交了一个功能请求,有deploy:load_schema在Capistrano的实现 。 在这种要求,我注意到, 在“ db:schema:loaddb:migrate ”的争论已经覆盖了Capistrano的讨论组中 ,并且有一些不愿意交换机deploy:cold任务使用db:schema:load超过db:migrate ,因为如果无意中运行,前者核武器整个数据库,而后者可能会抱怨和无害保释。 然而db:schema:load是在技术上更好的方法,因此,如果数据意外丢失的风险可以得到缓解,这将是值得切换。



Answer 4:

在Capistrano的3 /轨道4,默认部署语法发生了变化。 你可以这样做,而不是:

desc 'Deploy app for first time'
task :cold do
  invoke 'deploy:starting'
  invoke 'deploy:started'
  invoke 'deploy:updating'
  invoke 'bundler:install'
  invoke 'deploy:db_setup' # This replaces deploy:migrations
  invoke 'deploy:compile_assets'
  invoke 'deploy:normalize_assets'
  invoke 'deploy:publishing'
  invoke 'deploy:published'
  invoke 'deploy:finishing'
  invoke 'deploy:finished'
end

desc 'Setup database'
task :db_setup do
  on roles(:db) do
    within release_path do
      with rails_env: (fetch(:rails_env) || fetch(:stage)) do
        execute :rake, 'db:setup' # This creates the database tables AND seeds
      end
    end
  end
end

如果你是谨慎调用标准的手动部署的任务:cold任务(因为他们可能在即将到来的版本,或者改变您有一个自定义部署任务),你也可以简单地调用deploy:db_setup在运行之前deploy

要执行db:schema:load ,而不是db:setup ,你可以简单地改变rake任务,就像这样:

desc 'Load DB Schema'
task :db_schema_load do
  ...
        execute :rake, 'db:schema:load'
  ...
end


文章来源: db:schema:load vs db:migrate with capistrano