Dumping database from within a Rails project

Dumping a database is a trivial task. Nevertheless it takes time to copy & paste credentials when using mysqldump or the like. Aside from that it's pretty boring.

We have a script to quickly dump a MySQL database. It saves all output to dumps in your home directory. The script will create the directory and set proper permissions for you. A good place to put the following script into is ~/bin/dumple or /usr/local/bin/dumple when used by others on the machine. Remember to assign the executable flag: chmod +x ~/bin/dumple.

#!/usr/bin/env ruby

fail_gently = ARGV.include?("--fail-gently")

if ARGV.include?("-i")
  puts "*******************************************************"
  puts
  system("du -sh ~/dumps")
  puts
  puts "*******************************************************"
  exit
end

require "yaml"

config_path = 'config/database.yml'
unless File.exist?(config_path) 
  if fail_gently
    puts "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
    puts "*                                                             *"
    puts "*                                                             *"
    puts "*     Script is not called from inside a Rails project,       *"
    puts "*                                                             *"
    puts "*            THE DATABASE WILL NOT BE DUMPED.                 *"
    puts "*                                                             *"
    puts "*                                                             *"
    puts "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
    sleep 5
    exit
  else
    raise "Call me from inside a Rails project."
  end
end
config = YAML::load(File.open(config_path))

environment = ARGV.reject{ |arg| arg[0].chr == '-' }.first || 'production'
config = config[environment] or raise "No production environment found. Please do `dumple [env_name]`"

dump_dir = "#{ENV['HOME']}/dumps"
unless File.directory?(dump_dir)
  Dir.mkdir(dump_dir)
  system("chmod 700 #{dump_dir}")
end
dump_path = "#{dump_dir}/#{config['database']}_#{Time.now.strftime("%Y%m%d_%H%M%S")}.dump"

puts
puts "Dumping database for environment \"#{environment}\"..."

system "mysqldump -u\"#{config['username']}\" -p\"#{config['password']}\" #{config['database']} -r #{dump_path}"
system "chmod 600 #{dump_path}"

dump_size_kb = (File.size(dump_path) / 1024).round

puts "Dumped to #{dump_path} (#{dump_size_kb} KB)"
puts

Run the script at the root folder of a Rails project and it will (try to) dump the production database. To dump a database belonging to a different environment, give it as first parameter:

user@host:~/rails/current$ dumple dev.example.com

Dumping database for environment "dev.example.com"...
Dumped to /home/thomas/dumps/dev_example_20100723_091715.dump (4127 KB)

Maybe you spotted that --fail-gently can be given as argument and affects the way the script fails. This has to do with Unix exit codes. I'll tell you in the next article why we need it!

You can follow any response to this post through the Atom feed.

Avatar

Fri, 23 Jul 2010 09:48:00 GMT

by thomas

Tags:

  • Brady said 26 days later:

    I’ve tacked on a gzip compression option, available at:

    http://gist.github.com/532561

    Thanks for the original, works like a charm.

  • Thomas said 26 days later:

    Good idea, thanks for sharing!

Leave a comment