Capistrano Task to Load Production Data

I was working on a migration that had a decent chance of messing up my database and wanted assurance it would work with production data, not just my fixtures.

Building on Bojan Mihelac’s code to download files, I wrote a Capistrano task to load the production database into my local database. And then capistrano 1.4.0 was released with a built-in get method for downloading files. So if you have 1.4.0, you can just throw away that whole function.

# Get file remote_path from FIRST server targetted by # the current task and transfer it to local machine as path, SFTP required # def actor.get(remote_path, path, options = {}) execute_on_servers(options) do |servers| self.sessions[servers.first].sftp.connect do |tsftp| “Get #{remote_path} to #{path}” tsftp.get_file remote_path, path end end end

desc “Load production data into development database” task :load_production_data, :roles => :db, :only => { :primary => true } do require ‘yaml’

database = YAML::load_file(‘config/database.yml’)

filename = “dump.#{ ‘%Y-%m-%d_%H:%M:%S’}.sql” on_rollback { delete “/tmp/#{filename}” }

run “mysqldump -u #{database[‘production’][‘username’]} --password=#{database[‘production’][‘password’]} #{database[‘production’][‘database’]} > /tmp/#{filename}” do |channel, stream, data| puts data end get “/tmp/#{filename}”, filename exec “/tmp/#{filename}” exec “mysql -u #{database[‘development’][‘username’]} --password=#{database[‘development’][‘password’]} #{database[‘development’][‘database’]} < #{filename}; rm -f #{filename}” end

After adding the code to the tail of my config/deploy.rb, I ran cap load_production_data. Then I had a full copy of the production database to tinker with until I was content my migration was flawless.

Production data is also useful for other things. I can run complicated stats queries without worrying about bogging down the site, and see layout bugs that don’t happen unless there’s a few dozen tags on the page.