Skip to content

Instantly share code, notes, and snippets.

@aks
Forked from hopsoft/db.rake
Last active December 11, 2015 03:03
Show Gist options
  • Save aks/d2f065285465e3af440b to your computer and use it in GitHub Desktop.
Save aks/d2f065285465e3af440b to your computer and use it in GitHub Desktop.
Rails rake tasks for dump & restore of PostgreSQL databases
# lib/tasks/db.rake
namespace :db do
desc "Dumps the database to backups"
task :dump => :environment do
dump_fmt = 'c' # or 'p', 't', 'd'
dump_sfx = suffix_for_format dump_fmt
backup_dir = backup_directory true
cmd = nil
with_config do |app, host, db, user|
file_name = Time.now.strftime("%Y%m%d%H%M%S") + "_" + db + '.' + dump_sfx
cmd = "pg_dump -F #{dump_fmt} -v -h #{host} -d #{db} -f #{backup_dir}/#{file_name}"
end
puts cmd
exec cmd
end
desc "Show the existing database backups"
task :list => :environment do
backup_dir = backup_directory
puts "#{backup_dir}"
exec "/bin/ls -lt #{backup_dir}"
end
desc "Restores the database from a backup using PATTERN"
task :restore, [:pat] => :environment do |task,args|
if args.pat.present?
cmd = nil
with_config do |app, host, db, user|
backup_dir = backup_directory
files = Dir.glob("#{backup_dir}/*#{args.pat}*")
case files.size
when 0
puts "No backups found for the pattern '#{args.pat}'"
when 1
file = files.first
fmt = format_for_file file
if fmt.nil?
puts "No recognized dump file suffix: #{file}"
else
cmd = "pg_restore -F #{fmt} -v -c -C #{file}"
end
else
puts "Too many files match the pattern '#{args.pat}':"
puts ' ' + files.join("\n ")
puts "Try a more specific pattern"
end
end
unless cmd.nil?
Rake::Task["db:drop"].invoke
Rake::Task["db:create"].invoke
puts cmd
exec cmd
end
else
puts 'Please pass a pattern to the task'
end
end
private
def suffix_for_format suffix
case suffix
when 'c' then 'dump'
when 'p' then 'sql'
when 't' then 'tar'
when 'd' then 'dir'
else nil
end
end
def format_for_file file
case file
when /\.dump$/ then 'c'
when /\.sql$/ then 'p'
when /\.dir$/ then 'd'
when /\.tar$/ then 't'
else nil
end
end
def backup_directory create=false
backup_dir = "#{Rails.root}/db/backups"
if create and not Dir.exists?(backup_dir)
puts "Creating #{backup_dir} .."
Dir.mkdir_p(backup_dir)
end
backup_dir
end
def with_config
yield Rails.application.class.parent_name.underscore,
ActiveRecord::Base.connection_config[:host],
ActiveRecord::Base.connection_config[:database],
ActiveRecord::Base.connection_config[:username]
end
end
# dump the development db
rake db:dump
# dump the production db
RAILS_ENV=production rake db:dump
# what dumps exist?
rake db:list
# dump the production db & restore it to the development db
RAILS_ENV=production rake db:dump
rake db:restore[_prod]
# dump the dev DB and restore it into the test DB
RAILS_ENV=development rake db:dump
RAILS_ENV=test rake db:restore[_dev]
# note: config/database.yml is used for database configuration,
# but you will be prompted for the database user's password
# unless you have already setup PGPASS or use ~/.pgpass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment