Heroku 迁移不起作用

15

我在Heroku上运行了pg:reset命令,尝试运行db:migrate命令,所有迁移都会运行,但迁移失败并显示以下错误和跟踪信息:

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)>'

此处所示,有问题的行及其上一行是:

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)

这在本地运行没有任何问题,包括开发和生产环境。

有人经历过类似的情况吗?

2个回答

50
这是一个有趣的bug,可以忽略它。由于它试图进行db:structure:dump操作,说明您正在使用"sql"作为您的active_record.schema_format。在Heroku上,rake任务db:structure:dump将失败,因为pg_dump不在二进制路径中。有趣的是,Heroku声明不支持db:schema:dump,但如果您将模式格式设置为ruby,则可以正常工作。
在Rails 3中,只有当命令的退出代码为1时,dump任务才会引发错误。如果在基于unix的系统上找不到命令,则退出代码为127。因此,即使pg_dump命令在Rails 3上失败(实际上就是这样),它也不会引发错误,也不会停止rake任务。因此,任何使用sql架构格式的Rails 3用户都不会遇到此问题,因为它会静默失败。Rails 4中进行了重构以正确地引发错误,如果dump失败,则会导致db:migrate在Heroku上引发错误。然而,尽管它会出现rake aborted错误,但DDL实际上已经被执行和提交了。 可能的解决方案:
  • 忽略错误,因为迁移实际上已经运行。
  • 既然您不关心生产环境的结构转储,将schema_format设置为ruby。在config/environments/production.rb中:

    config.active_record.schema_format = :ruby
    
  • 如果出于某些原因您不想更改配置文件:请添加一个rake任务,其中包含以下内容以抑制错误:

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

我也遇到了同样的问题。我最初在application.rb中添加了以下行:config.active_record.schema_format = :sql,这是在Railscasts第334集中为Postgres搜索添加GIN索引后所做的。那么,现在是否可以安全地更改application.rb中的上述内容,或者应该将:sql行移动到development.rb中,并在production.rb中使用:ruby - memoht
3
为了在structure.sql文件中保留PostgreSQL的GIN索引,我建议将 :sql 保留在开发环境中。您可以在 application.rb 文件中保持它为 :sql,然后只需在 production.rb 中添加 :ruby 即可。这样,您就可以使开发和测试环境下的结构文件保持一致。请注意,不要改变原文意思。 - Lukas Eklund
4
太好了,我遇到了完全相同的问题!我收到的错误信息是(并通过谷歌搜索得到):Error: You must install at least one postgresql-client-<version> package. 这里为了易于搜索而添加。 - xmjw
1
另一个解决方案是安装postgresql-client以满足postgresql-client-common的pg_wrapper要求。 - jla

3

这个被接受的解决方案有些正确。Heroku在其运行时环境中确实有pg_dump

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

问题源于这个问题:https://github.com/rails/rails/issues/21226 该命令无法正确运行。

如果需要执行db:structure load,你可以使用$ heroku pg:psql
heroku pg:psql -a your-app-name <db/structure.sql

来自heroku rake db:structure:load failure

如果您需要转储,可以使用这篇文章https://devcenter.heroku.com/articles/heroku-postgres-import-export,也有专门的命令:

  $ 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

如果需要在运行迁移之前重置数据库,可以使用 $ heroku pg:reset 命令。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接