結果のファイルをサーバーに配置しますか、それともクライアントに配置しますか?
サーバー側
再利用や自動化が簡単なものが必要な場合は、Postgresqlに組み込まれているCOPYコマンドを使用できます。例:
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
このアプローチは完全にリモートサーバーで実行されます -ローカルPCに書き込めません。また、Postgresの「スーパーユーザー」(通常は「root」と呼ばれます)として実行する必要があります。これは、Postgresがそのマシンのローカルファイルシステムで厄介なことをするのを止めることができないためです。
SECURITY DEFINER
を使用できるため、実際にはスーパーユーザーとして接続する必要があるという意味ではありません(自動化は別の種類のセキュリティリスクになります)。 CREATE FUNCTION
のオプション スーパーユーザーであるかのように実行する関数を作成する 。
重要な部分は、セキュリティをバイパスするだけでなく、追加のチェックを実行する関数があることです。したがって、必要なデータを正確にエクスポートする関数を記述したり、さまざまなオプションを受け入れることができる関数を記述したりできます。厳格なホワイトリストを満たします。次の2つを確認する必要があります。
- どのファイル ユーザーがディスク上で読み取り/書き込みを許可する必要がありますか?たとえば、これは特定のディレクトリである可能性があり、ファイル名には適切なプレフィックスまたは拡張子が必要な場合があります。
- どのテーブル ユーザーはデータベースで読み取り/書き込みできる必要がありますか?これは通常、
GRANT
によって定義されます。 sはデータベース内にありますが、関数は現在スーパーユーザーとして実行されているため、通常は「範囲外」であるテーブルに完全にアクセスできます。おそらく、誰かがあなたの関数を呼び出して、「users」テーブルの最後に行を追加することを望まないでしょう…
厳しい条件を満たすファイルやテーブルをエクスポート(またはインポート)する関数の例を含め、このアプローチを拡張したブログ投稿を作成しました。
クライアント側
もう1つのアプローチは、クライアント側でファイル処理を行うことです。 、つまり、アプリケーションまたはスクリプト内。 Postgresサーバーは、コピー先のファイルを知る必要はありません。データを吐き出し、クライアントがそれをどこかに置きます。
この基本的な構文は、COPY TO STDOUT
です。 コマンド、およびpgAdminなどのグラフィカルツールがそれを素敵なダイアログにラップします。
psql
コマンドラインクライアント \copy
と呼ばれる特別な「メタコマンド」があります 、「実際の」COPY
と同じオプションをすべて使用します 、ただしクライアント内で実行されます:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
終了する;
はないことに注意してください 、SQLコマンドとは異なり、メタコマンドは改行で終了するためです。
ドキュメントから:
COPYをpsql命令\copyと混同しないでください。 \ copyは、COPYFROMSTDINまたはCOPYTOSTDOUTを呼び出してから、psqlクライアントにアクセス可能なファイルにデータをフェッチ/保存します。したがって、\ copyを使用する場合、ファイルのアクセス可能性とアクセス権はサーバーではなくクライアントに依存します。
アプリケーションプログラミング言語はかもしれません データのプッシュまたはフェッチもサポートされていますが、通常はCOPY FROM STDIN
を使用できません。 / TO STDOUT
入出力ストリームを接続する方法がないため、標準のSQLステートメント内。 PHPのPostgreSQLハンドラー(ではない PDO)には、非常に基本的なpg_copy_from
が含まれています およびpg_copy_to
PHP配列との間でコピーする関数。これは、大規模なデータセットには効率的でない場合があります。