23tux
23tux

Reputation: 14736

Rake task copy between databases

I have a Rails 4 app with a Mongoid database and want to introduce a sandbox environment for testing purpose. There is some data (two models), that I want to copy from the production db to the sandbox.

I would do this with a rake task, that is called by a cronjob. However, inside this rake task, I'm not sure how to establish two connections to the databases, and use the same model for different databases.

I was also thinking of doing it at the mongodb layer (like they do here How to copy a collection from one database to another in MongoDB), but one model consists of data, that only should be partially copied to the sandbox database. Therefore, I think I have to do it inside the Rails environment.

In this rake task, I can all my articles, but I don't know how to "push" them into the sandbox database:

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

Upvotes: 2

Views: 698

Answers (1)

23tux
23tux

Reputation: 14736

I finally found the solution myself. The key are the mongoid sessions you can define inside mongoid.yml.

If you want to copy production data to sandbox, you can define a second session inside your sandbox environment (you start the task in sandbox env, and it gives you access to the production database):

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

You can access the production_sync session by defining a separate class for the model you want to sync like this:

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

Now you can use this class to access the production database. If you want to copy all data from production to sandbox, do it like this:

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

I defined myself a rake task, that is called by a cronjob every day, and syncs data from production to sandbox.

One question remains: If you want to make sure, to not changing any data, some kind of read only mode would be useful (see here Make mongoid session read only).

Upvotes: 1

Related Questions