2

あらゆる種類の挿入ステートメントと時折の「\ connect」コマンドを含むデータベースダンプファイルがあります

問題は、 psql の-commands likeなどPG::Connection.exec()を受け入れないことです。\\i\c

ruby-pg (またはおそらく別の pg-gem) を使用して仕事をする方法はありますか?

データベースが別のホスト上にあるため、Unix ソケットを使用できず、postgresパスワードなしでユーザーとして接続できません。

4

3 に答える 3

1

pg_restoreのような psql コマンド ライン ツールを使用する方がおそらく簡単です。

pg_restore -d newdb db.dump

元のデータベースがホストされているボックスへの ssh アクセスがあり、どのテーブルをダンプする必要があるかがわかっている場合は、ボックスに ssh して、pg_dumpの出力をローカル データベースに直接パイプできます。何かのようなもの:

ssh user@original_database pg_dump -U remote_user_name -T schema_name.table_name mydb | psql -U local_user_name -d local_database
于 2012-07-12T17:38:10.190 に答える
0

バックスラッシュ コマンドは Postgres コマンドではないため、答えは「いいえ」です。これらは、デフォルトのコマンドライン クライアントであるpsqlコマンドです。これらのコマンドはlibpq APIの一部ではないため、サードパーティ ツールはこれらのコマンドを複製しません。

さて、そうは言っても、ファイル内の唯一のバックスラッシュ コマンドは \connect ですか? その場合、 \connect ステートメントからデータベース名を解析し、各 \connect ステートメントの後の最初の行から始まるチャンクにダンプ ファイルを分割することで、これを実装できるはずです。その時点で、そのチャンクの \connect ステートメントで指定されたデータベースへの接続に対して、通常どおり各チャンクを実行するだけです。

私の知る限り、ユーザーの資格情報を再検証する必要があるため、新しい接続を作成せずに別のデータベースに再接続する方法はありません。これは、psql が舞台裏で行う方法ですらあります。

\connect ステートメントが 1 つしかなく、それが CREATE ROLE などのステートメントの直後にある CREATE DATABASE ステートメントの直後にある場合、別のステップとしてデータベースを作成し、CREATE DATABASE ステートメントと \connect ステートメントの両方を削除すると、別の考えがあります。ファイルをチャンク化せずに実行できる場合があります。データベースを作成する前にデータベースに接続することはできず、接続中に新しいデータベースに変更することもできないため、2 つの接続が必要になることに注意してください。

于 2012-07-12T19:13:01.547 に答える
0

\connect 行でファイルを分割するなど、多くのことを試した後、今のところ「昔ながらのシェルスクリプトの方法」で実行することになりました...避けたかった方法です。でもどこかに行かなきゃいけない

私が今していることは次のとおりです。

  insert_command = "cat #{dump_file_path} | " +
        "ssh -p #{port} -i #{key} #{ssh_user}@#{db_host} " +
        "\"su - postgres -c 'cat > /tmp/rb_dump.sql && psql -f /tmp/rb_dump.sql ; rm /tmp/rb_dump.sql'\""

    Open3.popen3 insert_command do |stdin, stdout, stderr, t|
      unless t.value.to_s.include? "exit 0"
        <handle error>
      end
    end

私の意見では完全にハックですが、うまくいきます^^

私の他の解決策は、次のコードであり、大きな問題があります(以下に記載)

 def insert_database_dump(dump_file_handle, host, user, password, database = nil)
    begin
      pg = PG.connect(host: host, user: user, password: password, dbname: database)
      until dump_file_handle.eof?
        line = dump_file_handle.readline(";")
        if line =~ /connect\s(\w*)/
          line.gsub!("\\connect", "").strip!
          insert_database_dump(dump_file_handle, host, user, password, line)
        else
          pg.exec(line)
        end
      end
    ensure
      pg.finish unless pg.finished?
    end
  end

コードは次のことを行います (重要な部分のみ)。

  • 「;」までSQLから行を読み取ります (クエリは複数の行に分割されているため、改行まで読むだけでは機能しません
  • クエリを実行する
  • 行が「単語を接続する」のように見える場合、データベース名として「単語」が選択され、データベース名として「単語」を使用してメソッドが再度呼び出され、接続元の正しい行を指す現在のファイルハンドル続行。

メソッドがそれ自体を呼び出すためのより洗練された方法があるかもしれないという事実にもかかわらず、これは sql ダンプにコメントがない限り機能します。問題は、コメントが次のようになっていることです。

-- foo: bar; bam: baz;

したがって、「;」で分割すると、「-- foo: bar;」が実行されます。これはコメントであるため機能しますが、「bam: baz;」で失敗します。

現在、コメント行をその場で削除する簡単な解決策はありません。したがって、Open3 ソリューションは、私が見つけるまで実行する必要があります。

乾杯、ステファン

于 2012-07-16T13:52:14.083 に答える