最終的に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行で自由に組み合わせることができます。ただし、いずれの場合も、メタコマンドの引数は行の終わりを超えて続行できません。
異なるルールが後に em適用されます。 > \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つの信頼できる方法です。
- 皆さんの回答に感謝します。セミコロンで一時テーブルを作成した行を終了しなかったようです。そのため、'は作成されませんでした。現在、期待どおりに機能しています