数据库之间的Rake任务复制

时间:2015-01-23 16:57:09

标签: ruby-on-rails ruby mongodb rake rake-task

我有一个带有Mongoid数据库的Rails 4应用程序,并希望引入沙箱环境以进行测试。有一些数据(两个模型),我想从生产数据库复制到沙箱。

我会用rake任务执行此操作,该任务由cronjob调用。但是,在此rake任务中,我不确定如何建立与数据库的两个连接,并对不同的数据库使用相同的模型。

我还想在mongodb层做这件事(就像他们在这里做How to copy a collection from one database to another in MongoDB),但是一个模型由数据组成,只应部分复制到沙箱数据库。因此,我认为我必须在Rails环境中完成它。

在这个rake任务中,我可以发表所有文章,但我不知道如何推动"他们进入沙盒数据库:

namespace :sandbox do
  desc "Syncs production -> sandbox data"
    task(:sync => :environment) do |t, args|
      Article.all.each do |article|
        if my_model1.state == :active
          # here it should sync article to the sandbox models

          # and then, it should also sync all the comments to the sandbox models
          article.comments
        end
      end
    end
  end
end

1 个答案:

答案 0 :(得分:1)

我终于找到了解决方案。关键是你可以在mongoid.yml内定义的mongoid会话。

如果要将生产数据复制到沙箱,可以在沙箱环境中定义第二个会话(在沙箱环境中启动任务,它可以访问生产数据库):

sandbox:
  sessions:
    default:
      database: your_sandbox_db
      hosts:
        - localhost:27017
    production_sync:
      database: your_production_db
      hosts:
        - localhost:27017

您可以通过为要同步的模型定义单独的类来访问production_sync会话:

class ArticleProduction
  include Mongoid::Document
  include Mongoid::Attributes::Dynamic
  store_in collection: "articles", session: "production_sync"
end

现在您可以使用此类访问生产数据库。如果要将所有数据从生产复制到沙箱,请执行以下操作:

production_articles = ArticleProduction.map(&:attributes)
production_articles.each do |attributes|
  Article.create(attributes)
end

我为自己定义了一个rake任务,每天由cronjob调用,并将数据从生产同步到沙箱。

还有一个问题:如果你想确保不改变任何数据,某种只读模式会很有用(见Make mongoid session read only)。