web-dev-qa-db-ja.com

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コピーコマンドが一時テーブルを表示できないというエラーが表示されるので、クライアントのコピーコマンドが実際に同じpostgresを使用してはいけないと思いますpsqlとしてのセッション。

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

8
jkebinger

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

最初に、コマンドラインでバージョン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

fileの最後で省略可能である(暗黙的に終了する)終了セミコロンに注意してください。ただし、他のSQLステートメントの後に、またpsqlでインタラクティブに実行する場合は最後のステートメントの後にも必要です。

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

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

ただし、after\copyには異なるルールが適用されます。基本的に、psqlは\copyの後で自動的にSQLモードに戻ります。

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


それはさておき、\copypsqlメタコマンド )の代わりに_(COPYSQLコマンド )を使用することを検討しましたか?

もちろん、この場合、ターゲットファイルはサーバーのローカルクライアントではない= /でなければなりません。また、異なるファイル権限が適用されます。 マニュアル

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

16