如何使用 Capistrano gem 为生产数据库播种?

Posted

技术标签:

【中文标题】如何使用 Capistrano gem 为生产数据库播种?【英文标题】:How to seed the production database using the Capistrano gem? 【发布时间】:2011-11-19 16:35:31 【问题描述】:

我正在使用 Ruby on Rails 3.0.9,我想为 生产数据库 播种,以便添加一些记录而不重新构建所有数据库(即是,不删除所有现有记录,而只是添加一些尚不存在的记录)。我愿意这样做,因为需要新数据才能使应用程序正常工作。

因此,由于我使用的是 Capistrano gem,因此我在控制台中运行 cap -T 命令以列出所有可用命令并了解如何实现我的目标:

$ cap -T
=> ...
=> cap deploy:seed          # Reload the database with seed data.
=> ...

我不确定“使用种子数据重新加载数据库”中的“重新加载”一词。句子。所以,我的问题是:如果我在本地机器上的控制台中运行cap deploy:seed 命令,播种过程会删除生产数据库中的所有现有数据,然后填充它,还是该命令只是将新数据添加到我打算做那个数据库?

【问题讨论】:

【参考方案1】:

如果你使用的是 bundler,那么 capistrano 任务应该是:

namespace :deploy do
  desc "reload the database with seed data"
  task :seed do
    run "cd #current_path; bundle exec rake db:seed RAILS_ENV=#rails_env"
  end
end

它可能被放置在一个单独的文件中,例如 lib/deploy/seed.rb 并使用以下命令包含在您的 deploy.rb 文件中:

load 'lib/deploy/seed'

【讨论】:

什么原因可能会放在单独的文件中? 有时最好将通用定义放在一个单独的文件中,这样很容易移植到另一个项目。如果您添加了 lib/deploy/seed.rb 文件,请将以下内容添加到 deploy.rb 文件的顶部以包含它:load 'lib/deploy/seed' 非常感谢!!!运行 "cd #current_path; bundle exec rake db:seed RAILS_ENV=#​​rails_env" 像魅力一样工作:D 实际上,您希望:run "cd #release_path && bundle exec rake db:seed RAILS_ENV=#rails_env" 您可能希望处于您已部署的版本中(并在滚动代码之前播种)。 && 还确保您可以更改目录,如果您不能,则会失败 别忘了指定你想要运行它的角色。如果您有多台机器,您可能会考虑只在您的数据库上运行它。 task :seed, :roles => :db do ...【参考方案2】:

这对我有用:

task :seed do
 puts "\n=== Seeding Database ===\n"
 on primary :db do
  within current_path do
    with rails_env: fetch(:stage) do
      execute :rake, 'db:seed'
    end
  end
 end
end

capistrano 3,Rails 4

【讨论】:

把那个放到 lib/capistrano/tasks 并命名为 XXX.rake +1 为with rails_env: fetch(:stage) 的一个干净整洁的用法【参考方案3】:

使用 Capistrano 3、Rails 4 和 SeedMigrations,我在 /lib/capistrano/tasks 下创建了一个 Capistrano seed.rb 任务:

namespace :deploy do
  desc 'Runs rake db:seed for SeedMigrations data'
  task :seed => [:set_rails_env] do
    on primary fetch(:migration_role) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, "db:seed"
        end
      end
    end
  end

  after 'deploy:migrate', 'deploy:seed'
end

我的种子迁移现在与我的架构迁移完全分开,并按照 db:migrate 进程运行。多么快乐! :)

【讨论】:

我认为需要将其命名为 seed.rake 才能使用默认 Capfile 自动加载。【参考方案4】:

尝试在您的 deploy.rb 中添加类似的内容:

namespace :deploy do
  desc "reload the database with seed data"
  task :seed do
    run "cd #current_path; rake db:seed RAILS_ENV=#rails_env"
  end
end

【讨论】:

【参考方案5】:

cap deploy:seed 基本上应该是对rake db:seed 的引用。它不应该删除现有数据,除非您在 seed.rb 中指定这样做。

“重新加载”这个词的最佳假设是 :seed 是一个无状态命令,我不会自动知道它在哪里停止,就像常规的 Rails 迁移一样。因此,从技术上讲,每次运行种子时,您总是会“重新加载”种子。 ...一个疯狂的猜测,但听起来不错,不是吗?


请查看下方Javier Vidal的答案

【讨论】:

cap deploy:seed 抛出“任务 `deploy:seed' 不存在” rails$ cap -e deploy:seed The task 'deploy:seed' does not exist. 答案不在下面,而是在上面:P【参考方案6】:

在与 capistrano-rails gem 作者讨论后,我决定在单独的 gem 中实现此类任务。我认为这有助于遵循 DRY 的想法,而不是一遍又一遍地执行相同的任务。

希望对你有帮助:https://github.com/dei79/capistrano-rails-collection

【讨论】:

在 dei79 的 github 页面之后,我得到了一个快速的结果: 1. Gemfile: gem 'capistrano-rails-collection' 2. bundle install 3. Capfile: require 'capistrano/rails/collection' 4. cap production rails:rake:db:seed

以上是关于如何使用 Capistrano gem 为生产数据库播种?的主要内容,如果未能解决你的问题,请参考以下文章

Capistrano:我可以为整个 cap 会话设置一个环境变量吗?

如何在 Ubuntu 中使用 gem?

为 Web 开发提供的 10 个 Ruby on Rails Gems

Capistrano、防火墙和隧道

如何从 Capistrano 运行 rake 任务?

Capistrano 生产部署问题