" pg_dump:无效选项 - 我"迁移时

时间:2016-03-14 23:20:36

标签: ruby-on-rails postgresql

当我在我的Rails项目(3.2.22.2)上运行rake db:migrate时,我得到pg_dump: invalid option -- i。这里有完整的痕迹:

Celluloid 0.17.1.1 is running in BACKPORTED mode. [ http://git.io/vJf3J ]
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
pg_dump: invalid option -- i
Try "pg_dump --help" for more information.
rake aborted!
Error dumping database
/Users/jasonswett/.rvm/gems/ruby-2.1.4@bm43/gems/activerecord-3.2.22.2/lib/active_record/railties/databases.rake:429:in `block (3 levels) in <top (required)>'
/Users/jasonswett/.rvm/gems/ruby-2.1.4@bm43/gems/activerecord-3.2.22.2/lib/active_record/railties/databases.rake:202:in `block (2 levels) in <top (required)>'
/Users/jasonswett/.rvm/gems/ruby-2.1.4@bm43/gems/activerecord-3.2.22.2/lib/active_record/railties/databases.rake:196:in `block (2 levels) in <top (required)>'
/Users/jasonswett/.rvm/gems/ruby-2.1.4@bm43/bin/ruby_executable_hooks:15:in `eval'
/Users/jasonswett/.rvm/gems/ruby-2.1.4@bm43/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => db:structure:dump
(See full trace by running task with --trace)

我注意到有bugfix in Rails与此问题有关。错误修复似乎没有应用于Rails版本&lt; 4,因为它不是安全修复,这是有道理的。

我不明白的是我现在应该做的事情。如果有3.2.x的修复程序,我还没能找到它。我想如果3.2.x没有修复,我猜这意味着我必须升级到Rails 4.x,这看起来有点激烈。我怀疑这是否是唯一的解决方案。为什么这个问题最近才突然出现?

任何建议都表示赞赏。

5 个答案:

答案 0 :(得分:13)

不太可能存在修复,因为它不是安全问题。即使是这样,我也不确定他们是否正在修补3.x.

问题在于db:structure:dump任务:

https://github.com/rails/rails/blob/v3.2.22.2/activerecord/lib/active_record/railties/databases.rake#L428

最简单的事情是复制该任务(413 - 448)并将其放入您自己的lib / tasks目录中,在其周围包裹namespace db,调整pg_dump命令(删除-i)并且您的任务应该覆盖内置任务。

答案 1 :(得分:13)

我还遇到了Rails 3.2.22这个问题。在4.2.5中看起来好像是fixed,但对于我们的情况,升级Rails并不是很实用。

在考虑了一些选项之后,我最终完成了覆盖db:structure:dump之后调用的默认rake任务db:migrate的路径。

我创建了一个文件tasks/database.rake,并将来自不同ActiveRecord方法的各个部分组合在一起以创建新的db:structure:dump任务。现在,在执行db:migrate等时调用此新任务而不是默认任务。

Rake::Task["db:structure:dump"].clear
namespace :db do
  namespace :structure do
    desc "Overriding the task db:structure:dump task to remove -i option from pg_dump to make postgres 9.5 compatible"
    task dump: [:environment, :load_config] do
      config = ActiveRecord::Base.configurations[Rails.env]
      set_psql_env(config)
      filename =  File.join(Rails.root, "db", "structure.sql")
      database = config["database"]
      command = "pg_dump -s -x -O -f #{Shellwords.escape(filename)} #{Shellwords.escape(database)}"
      raise 'Error dumping database' unless Kernel.system(command)

      File.open(filename, "a") { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
      if ActiveRecord::Base.connection.supports_migrations?
        File.open(filename, "a") do |f|
          f.puts ActiveRecord::Base.connection.dump_schema_information
          f.print "\n"
        end
      end
      Rake::Task["db:structure:dump"].reenable
    end
  end

  def set_psql_env(configuration)
    ENV['PGHOST']     = configuration['host']          if configuration['host']
    ENV['PGPORT']     = configuration['port'].to_s     if configuration['port']
    ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password']
    ENV['PGUSER']     = configuration['username'].to_s if configuration['username']
  end
end

此代码是专门为我们的项目创建的,因此如果您有任何其他自定义配置设置为db_dir,则需要进行相应调整。

答案 2 :(得分:3)

此错误是因为&#39; -i&#39;在9.5.X及更高版本中描述的方法。 修复了Rails -v&#39; 4.2.5&#39;并且您可以将Rails更新为此版本或更高版本。 但是如果你需要快速的方法我认为你会对它感到满意(它只是黑客,如果你有点怀疑或者你不同意它就不要使用它!):

1)找到这个文件:&#39; postgresql_database_tasks.rb&#39; (就我而言):

/Users/YourUserName/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activerecord-4.2.4/lib/active_record/tasks/postgresql_database_tasks.rb

2)打开它,找到并编辑下面的行,然后删除&#39; -i&#39;来自字符串:

command = "pg_dump -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"

3)保存此文件并再次启动rake任务! 那个!

答案 3 :(得分:1)

我在尝试运行rake db:migrate后最近在Rails 4.2.1中遇到了这个错误。

我能够通过升级到Rails 4.2.6并让bundle update完成所有相关宝石的工作来克服它。

希望对别人有用。

答案 4 :(得分:0)

或者,您可以修改本地pg_dump以删除-i选项。虽然个别安装可能有所不同,但以下是我所做的编辑:

该命令遍历其所有参数(第36行):

for (my $i = 0; $i <= $#ARGV; ++$i) {

找到条件(第39行):

if ($ARGV[$i] eq '--cluster') {

添加以下内容(第57行):

} elsif ($ARGV[$i] eq '-i') {
    splice @ARGV, $i, 1;
}