簡體   English   中英

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

[英]db:schema:load vs db:migrate with capistrano

我有一個rails應用程序,我正在移動到另一台服務器,我想我應該使用db:schema:load來創建mysql數據庫,因為它是推薦的。 我的問題是我使用capistrano進行部署,而且似乎默認為rake db:migrate。 有沒有辦法改變這個或使用db:migrate的capistrano有充分理由?

為什么要使用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

我在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

爬上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

我的改進是......

  • 將它包裝在transaction do ,以便Capistrano在中止后進行適當的回滾。
  • 執行db:setup而不是db:schema:load ,這樣如果數據庫尚不存在,它將在加載模式之前創建。

這是Andres Jaan Tack的一個很好的答案。 我只是想補充幾點意見。

首先,這是Andres deploy:load_schema的改進版本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的功能請求deploy:load_schema在Capistrano中實現的deploy:load_schema 在該請求中,我注意到Capistrano討論組已經討論了' db:schema:loaddb:migrate '的爭論 ,並且有些人不願意將deploy:cold任務切換為使用db:schema:load over db:migrate ,因為如果無意中運行,前者會破壞整個數據庫,而后者可能會無害地抱怨和保釋。 然而db:schema:load在技​​術上是更好的方法,因此如果可以減輕意外數據丟失的風險,那么值得切換。

在Capistrano 3 / Rails 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之前調用deploy:db_setup

要執行db:schema:load而不是db:setup ,您只需更改rake任務,如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM