railsuser400
railsuser400

Reputation: 1023

Migrate not working on Heroku

I've run pg:reset on Heroku and on trying to run db:migrate, all migrations run but the migration fails with the following error and trace:

rake aborted!
Error dumping database
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.rc2/lib/active_record/tasks/postgresql_database_tasks.rb:55:in `structure_dump'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.rc2/lib/active_record/tasks/database_tasks.rb:142:in `structure_dump'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.rc2/lib/active_record/railties/databases.rake:288:in `block (3 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.rc2/lib/active_record/railties/databases.rake:51:in `block (2 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.rc2/lib/active_record/railties/databases.rake:45:in `block (2 levels) in <top (required)>'

As can be seen here the problematic line and the one above it are:

command = "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
raise 'Error dumping database' unless Kernel.system(command)

This works locally without any problems, both in development and production environments.

Has anyone experienced anything like this?

Upvotes: 15

Views: 7791

Answers (2)

Schneems
Schneems

Reputation: 15828

The accepted solution is somewhat correct. Heroku does have pg_dump on its runtimes

$ heroku run bash
$ which pg_dump
/usr/bin/pg_dump

The problem comes from this issue: https://github.com/rails/rails/issues/21226 the command cannot be run correctly.

If you need to do a db:structure load instead you can use the $ heroku pg:psql

heroku pg:psql -a your-app-name <db/structure.sql

From heroku rake db:structure:load failure.

If you need to dump you can use this article https://devcenter.heroku.com/articles/heroku-postgres-import-export there's also dedicated commands:

  $ heroku pg:pull <REMOTE_SOURCE_DATABASE> <TARGET_DATABASE>  #  pull from REMOTE_SOURCE_DATABASE to TARGET_DATABASE
  $ heroku pg:push <SOURCE_DATABASE> <REMOTE_TARGET_DATABASE>  #  push from SOURCE_DATABASE to REMOTE_TARGET_DATABASE

If you need to reset your database before running migrations you can use $ heroku pg:reset

Upvotes: 3

Lukas Eklund
Lukas Eklund

Reputation: 6138

This is an interesting bug that, as it turns out, can be ignored. Based on the fact it's attempting to do a db:structure:dump, you are using 'sql' as your active_record.schema_format. The rake task db:structure:dump will fail on heroku because pg_dump is (unsurprisingly) not in the binary path. Interestingly enough, Heroku states that db:schema:dump is not supported but if you set the schema format to ruby, it works fine.

In Rails 3, the dump task would only raise an error is the exit code of the command was 1. On unix based systems if the command is not found, the exit code is 127. So even if the pg_dump command fails on rails 3 (which it does), it won't raise an error and it won't halt the rake task. So anyone using a sql schema format with Rails 3 wouldn't have this issue because it would fail silently. The refactor in Rails 4 to properly raise an error if the dump failed causes db:migrate to raise an error on Heroku. However, even though it errors with rake aborted the ddl is actually performed and committed.

Possible solutions:

  • Ignore the error as the migrations are actually running.
  • Since you don't care about the structure dump on production, set the schema_format to ruby. In config/environments/production.rb:

    config.active_record.schema_format = :ruby
    
  • If for some reason you don't want to change the config file: add a rake task with the following to suppress the error:

    if Rails.env == 'production'
        Rake::Task["db:structure:dump"].clear
    end
    

Upvotes: 50

Related Questions