Postgresクライアントコピー(\ copy)コマンドは'一時テーブルにアクセスできませんか?

最終的にpsql-fを使用して実行するデータをエクスポートするSQLコマンドのリストを生成しています。クエリはすべて同じデータのサブセットを取得します。そのため、資格を除外して、適格なユーザーIDのリストを次のような一時テーブルに配置すると思いました。

create temporary table tmp_export_users as (select id from users where ...) 

次に、それを参照してください。 \ copyコマンドのような

\copy (select ... from table where user_id in (select id from tmp_export_users)) TO "filename.csv" WITH CSV HEADER 

これらはすべて同じファイルに1行に1つずつあり、実行すると-fコピーコマンドで発生するエラーが発生します。 “一時テーブルが表示されるので、clientcopyコマンドが実際にpsqlと同じpostgresセッションを使用してはならないのではないかと思います。

それは正しいですか?その動作を変更する方法はありますか?

回答

\copy は一時テーブルを使用できます。

最初に、バージョン 9.0 コマンドラインで。
次に、SQLとpsqlメタコマンド\copyを使用してファイルを作成しました。複数の一時テーブル。それは私にとってもうまくいきました。

CREATE TEMP TABLE tmp as SELECT * FROM tbl; \copy (SELECT * FROM tmp JOIN tbl USING (id)) TO "/var/lib/postgres/test1.csv"; 

電話:

psql -p5432 mydb -f test.sql 

終了に注意してくださいセミコロン。ファイルの最後ではオプションですが(暗黙的に終了します)、他のSQLステートメントの後、およびpsqlでインタラクティブに実行する場合は最後のステートメントの後に必要です。

通常は、psqlメタコマンドをSQL と同じ行に混在させることはできませんpsql -fごとに実行されるファイル内の psqlのマニュアルを引用します:

引数の解析は最後に停止します行、または引用符で囲まれていない別の円記号が見つかった場合。引用符で囲まれていない円記号は、新しいメタコマンドの開始と見なされます。特別なシーケンス\\(2つの円記号)は、引数の終わりを示し、SQLコマンドがある場合はそれを解析し続けます。そうすれば、SQLコマンドとpsqlコマンドを1行で自由に組み合わせることができます。ただし、いずれの場合も、メタコマンドの引数は行の終わりを超えて続行できません。

異なるルールが後に \copyただし。基本的に、psqlは\copyの後に自動的にSQLモードに戻ります。参照:

しかし、すべてのコマンドが別々の行にあると書きました。だから、それはあなたの場合の説明ではありません。


それはさておき、 COPY\copy(\copyの代わりに、div> SQLコマンド psqlメタコマンド)?

もちろん、ターゲットファイルはこの場合はクライアントではなくサーバーのローカル。また、さまざまなファイル権限が適用されます。 マニュアル

COPYコマンドは、クライアントアプリケーションではなく、サーバーによって直接読み書きされます。したがって、クライアントではなく、データベースサーバーマシン上に存在するか、データベースサーバーマシンにアクセスできる必要があります。これらは、クライアントではなく、PostgreSQLユーザー(サーバーが実行されているユーザーID)にアクセス可能であり、読み取りまたは書き込み可能である必要があります。

コメント

  • copyはpostgresユーザーとして実行されます。\ copyはcopyをラップしてstdoutに書き込み、送信先のファイルにリダイレクトします。 psqlを呼び出し、\ oを使用して出力をファイルに送信してから、stdoutにコピーを実行して、同様の効果を得ることができます。
  • スーパーユーザー(postgres)を使用して回答でテストを実行したことを確認します。 )およびダミーユーザー。どちらも私のために働きます。 v8.4でも同じ結果が得られます。
  • そうです、postgresunixユーザーが/ tmpなどにアクセスできるかどうかは、SELinuxがインストールされているかどうかや、すぐに使用できるかどうかなどによって異なります。 \ copyまたはcopyto stdoutは、間違いなく、copyを使用するための2つの信頼できる方法です。
  • 皆さんの回答に感謝します。セミコロンで一時テーブルを作成した行を終了しなかったようです。そのため、'は作成されませんでした。現在、期待どおりに機能しています

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です