9

Hi I have a ruby on rails app hosted on heroku and it is using mysql as database.

Now I have to take backup of the database to my local machine. But I am getting issues while taking backup.

For this I installed taps gem and I am using following commands for it

heroku pg:pull mysql2://username@hostname.cleardb.com/heroku_database  local_database --app my_app

but it is giving error as !Your app has no databases.

Can any one guide me how to pull mysql database from heroku to local machine.

EDIT

I have used following syntax for the command

heroku pg:pull <REMOTE_SOURCE_DATABASE> <LOCAL_TARGET_DATABASE>

and for getting REMOTE_SOURCE_DATABASE I have used following command

 heroku config:get DATABASE_URL --app my_app

I refer this link1 and link2 for more detailed heroku documentation.

Wilson Hauck
  • 2,094
  • 1
  • 11
  • 19
I-am-simple-user
  • 409
  • 7
  • 19
  • Mysql in your local.. right or both in local and host is MySql ? – Arup Rakshit Feb 26 '15 at 08:13
  • I'm not a MySql guy but I think one way is next: connect to remote database with one of the MySql administrative tools and DATABASE_URL provided by ClearDB and dump data to local machine, then load this dumped data into your existent local database. Then migrate to PostgreSQL and be happy all the time, as Heroku has amazing support for such kind of RDBMS – atomdev Feb 26 '15 at 09:17
  • And one more comment: I think _heroku pg:pull_ is command only for Heroku Postgres service, so as you have not pg database you see error. On earlier days when heroku supported _taps_ , there was command like _heroku db:pull_ and user was able to migrate data between differnet kind of databases but now this functionality is gone. – atomdev Feb 26 '15 at 09:22
  • @rubykid so there is not any direct way. – I-am-simple-user Feb 26 '15 at 09:39
  • @ShrikantKhandare I'm not experienced enough in mysql but I think no. With postgres you can do dump with one command in terminal and there is must be the same way in mysql world. For example like this: [Copy mysql database from remote server to local computer](http://stackoverflow.com/questions/15435144/copy-mysql-database-from-remote-server-to-local-computer) – atomdev Feb 26 '15 at 09:55
  • This is odd. Heroku uses PostGRES... are you 100% sure you are using MySQL in heroku? Do you see a PG add-on? – Don P Mar 17 '15 at 07:37
  • yes, I have already checked – I-am-simple-user Mar 17 '15 at 07:55

3 Answers3

8

The pg:pull command only works with Postgres databases in your Heroku app. But, you are using a third-party MySQL provider. Your database is hosted on the ClearDB servers and it's available to anyone with the right credentials, including both your app server on Heroku and your dev machine.

Even though there aren't special commands to pull the database, you don't need any - plain mysqldump should do.

mysqldump -h hostname.cleardb.com -u username heroku_database | mysql local_database

Leonid Shevtsov
  • 14,024
  • 9
  • 51
  • 82
2

Running $heroku config | grep ^DATABASE will give you something like this:

DATABASE_URL: mysql2://username:password@host/dbname?reconnect=true`

From there you can construct your db dump command:

mysqldump -h host -p -u username dbname | mysql local_database

This will prompt you for the password which you received from the previous command. If you wanted to create a script that would automatically include the password from the heroku command you could do something like this:

mysqldump -u username --password=`heroku config | grep ^DATABASE | sed 's/.*[a-z0-9][a-z0-9]*:\([a-z][a-z0-9]*\).*/\1/'` -h host dbname | mysql cedric

In this way you can have a script that will import the database without requiring any user input but also does not expose the password to your database.

gabeodess
  • 2,006
  • 21
  • 13
2

(IMPORTANT DISCLAIMER: You MUST have your database.yml configured correctly in order for this to work. I am not responsible for any data you lose as a result of running the below script.)

For Ruby on Rails users ... you could consider writing a Rake task like these db:clone tasks below.

I find myself using this script constantly to clone down from production to development. It's way easier than remembering the mysqldump syntax, much less all of the usernames and passwords involved ...

To clone from production to development:

rake db:clone:production

To clone from staging to development:

rake db:clone:staging

To clone from production to staging:

rake db:clone:production_to_staging

And here's the code enjoy (and be careful in setting up your database.yml):

namespace :db do
  namespace :clone do

    class << self
      %w(development test staging production).each do |env|
        define_method("#{env}_db") do
          Rails.configuration.database_configuration[env]
        end
      end
    end

    def clone_db(from_db, to_db)
      start_time = Time.now
      puts "Cloning Remote DB...."
      system("mysqldump -h#{from_db['host']} -u#{from_db['username']} -p#{from_db['password']} #{from_db['database']} | mysql #{to_db['database']} -u#{to_db['username']} -p#{to_db['password']}")
      puts "Import Successful"
      end_time = Time.now
      puts "===================="
      puts "Job Completed: #{end_time - start_time} Seconds"
    end

    task :staging => :environment do
      clone_db(staging_db, development_db)
    end

    task :production => :environment do
      clone_db(production_db, development_db)
    end

    task :production_to_staging => :environment do
      clone_db(production_db, staging_db) if Rails.env.staging?
    end

  end
end
aldefouw
  • 533
  • 1
  • 4
  • 12
  • This script will probably work, but be aware that you should never work with real production data in a non-production environment. Always anonymise the data first. – jewilmeer Aug 16 '22 at 07:33