あらゆる種類の挿入ステートメントと時折の「\ connect」コマンドを含むデータベースダンプファイルがあります
問題は、 psql の-commands likeなどPG::Connection.exec()
を受け入れないことです。\
\i
\c
ruby-pg (またはおそらく別の pg-gem) を使用して仕事をする方法はありますか?
データベースが別のホスト上にあるため、Unix ソケットを使用できず、postgres
パスワードなしでユーザーとして接続できません。
あらゆる種類の挿入ステートメントと時折の「\ connect」コマンドを含むデータベースダンプファイルがあります
問題は、 psql の-commands likeなどPG::Connection.exec()
を受け入れないことです。\
\i
\c
ruby-pg (またはおそらく別の pg-gem) を使用して仕事をする方法はありますか?
データベースが別のホスト上にあるため、Unix ソケットを使用できず、postgres
パスワードなしでユーザーとして接続できません。
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
バックスラッシュ コマンドは Postgres コマンドではないため、答えは「いいえ」です。これらは、デフォルトのコマンドライン クライアントであるpsqlコマンドです。これらのコマンドはlibpq APIの一部ではないため、サードパーティ ツールはこれらのコマンドを複製しません。
さて、そうは言っても、ファイル内の唯一のバックスラッシュ コマンドは \connect ですか? その場合、 \connect ステートメントからデータベース名を解析し、各 \connect ステートメントの後の最初の行から始まるチャンクにダンプ ファイルを分割することで、これを実装できるはずです。その時点で、そのチャンクの \connect ステートメントで指定されたデータベースへの接続に対して、通常どおり各チャンクを実行するだけです。
私の知る限り、ユーザーの資格情報を再検証する必要があるため、新しい接続を作成せずに別のデータベースに再接続する方法はありません。これは、psql が舞台裏で行う方法ですらあります。
\connect ステートメントが 1 つしかなく、それが CREATE ROLE などのステートメントの直後にある CREATE DATABASE ステートメントの直後にある場合、別のステップとしてデータベースを作成し、CREATE DATABASE ステートメントと \connect ステートメントの両方を削除すると、別の考えがあります。ファイルをチャンク化せずに実行できる場合があります。データベースを作成する前にデータベースに接続することはできず、接続中に新しいデータベースに変更することもできないため、2 つの接続が必要になることに注意してください。
\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 ダンプにコメントがない限り機能します。問題は、コメントが次のようになっていることです。
-- foo: bar; bam: baz;
したがって、「;」で分割すると、「-- foo: bar;」が実行されます。これはコメントであるため機能しますが、「bam: baz;」で失敗します。
現在、コメント行をその場で削除する簡単な解決策はありません。したがって、Open3 ソリューションは、私が見つけるまで実行する必要があります。
乾杯、ステファン