【问题标题】:"pg_dump: invalid option -- i" when migrating迁移时“pg_dump:无效选项--i”
【发布时间】:2016-03-14 23:20:35
【问题描述】:

当我在我的 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 版本

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

欢迎提出任何建议。

【问题讨论】:

    标签: ruby-on-rails postgresql


    【解决方案1】:

    不太可能有修复,因为它不是安全问题。即使是这样,我也不确定他们是否正在修补 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),您的任务应该覆盖已构建的在任务中。

    【讨论】:

    • 啊,所以基本上写我自己的rake db:migrate 版本(通过复制Rails 源代码)并去掉-i?
    • 为了让它工作,我必须在开头添加Rake::Task["db:structure:dump"].clear并将this line更改为Rake::Task["db:structure:dump"].reenable
    【解决方案2】:

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

    在考虑了一些选项后,我最终选择了覆盖默认 rake 任务 db:structure:dump,该任务在 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,则需要进行相应调整。

    【讨论】:

      【解决方案3】:

      这个错误是因为 '-i' 方法在 9.5.X 和更高版本中被弃用了。 在 Rails -v '4.2.5' 中修复了错误,您可以将 Rails 更新到此版本或更高版本。 但是如果你需要快速的方法我想你会满意的(它只是hack,如果你有一点怀疑或者你不同意它,请不要使用它!):

      1) 找到这个文件:'postgresql_database_tasks.rb'(在我的例子中是):

      /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) 打开它,找到并编辑下面的行,从字符串中删除'-i':

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

      3) 保存此文件并再次开始您的 rake 任务! 就是它!

      【讨论】:

      • 节省了我的时间。如果 spring 像我一样运行,编辑后在终端运行killall ruby
      【解决方案4】:

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

      我能够通过升级到 Rails 4.2.6 并让 bundle update 来解决所有相关问题。

      希望对他人有用。

      【讨论】:

        【解决方案5】:

        或者,您可以编辑本地 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;
        }
        

        【讨论】:

        • 你是怎么做到的?我检查了我的,我的 postgre12 的 pg_dump 是一个二进制文件。
        • @SamuelDev 哦,好吧,我的本地 pg_dump 不是二进制文件,使用的是 Ubuntu 16。我相信本地设置会有所不同。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        • 2020-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多