web-dev-qa-db-ja.com

PostgreSQLからのPL/pgSQL出力をCSVファイルに保存する

PostgreSQLデータベースからのPL/pgSQL出力をCSVファイルに保存する最も簡単な方法は何ですか?

私はPostgreSQL 8.4をpgAdmin IIIとPSQLプラグインと共に使っています。

783
Hoff

結果のファイルをサーバーまたはクライアントに作成しますか?

サーバ側

簡単に再利用したり自動化したい場合は、Postgresqlの組み込みの COPY コマンドを使用できます。例えば.

Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',';

このアプローチは完全にリモートサーバーで実行されます-ローカルPCに書き込むことができません。 Postgresは、そのマシンのローカルファイルシステムで厄介なことを行うのを止めることができないため、Postgresの「スーパーユーザー」(通常は「ルート」と呼ばれます)として実行する必要もあります。

を使用してSECURITY DEFINERオプションをCREATE FUNCTION を使用してスーパーユーザーであるかのように実行します

重要な部分は、セキュリティをバイパスするだけでなく、関数が追加のチェックを実行することです-したがって、必要な正確なデータをエクスポートする関数を記述したり、さまざまなオプションを受け入れることができるものを記述したりできます厳格なホワイトリストを満たします。次の2つのことを確認する必要があります。

  1. どのfilesは、ユーザーがディスク上で読み取り/書き込みを許可されるべきですか?たとえば、これは特定のディレクトリであり、ファイル名には適切なプレフィックスまたは拡張子が必要になる場合があります。
  2. ユーザーはどのtablesでデータベースの読み取り/書き込みを行うことができますか?これは通常、データベース内のGRANTsによって定義されますが、関数は現在スーパーユーザーとして実行されているため、通常「範囲外」にあるテーブルには完全にアクセスできます。誰かがあなたの関数を呼び出して「ユーザー」テーブルの最後に行を追加できるようにしたくないでしょう。

私は このアプローチを拡張するブログ投稿を書きました 厳密な条件を満たすファイルとテーブルをエクスポート(またはインポート)する関数の例を含む。


クライアント側

もう1つの方法は、クライアント側でファイル処理を行う、つまり、アプリケーションまたはスクリプトです。 Postgresサーバーは、コピー先のファイルを知る必要はありません。単にデータを吐き出し、クライアントはそれをどこかに置きます。

この基礎となる構文はCOPY TO STDOUTコマンドであり、pgAdminのようなグラフィカルツールがNiceダイアログでそれをラップします。

psqlコマンドラインclientには、\copyと呼ばれる特別な「メタコマンド」があります。これは、「real」と同じオプションをすべて取ります。 COPY、ただしクライアント内で実行されます:

\copy (Select * From foo) To '/tmp/test.csv' With CSV

SQLコマンドとは異なり、メタコマンドは改行で終了するため、終了_;がないことに注意してください。

ドキュメントから

COPYとpsqlの命令\ copyを混同しないでください。\copyは、COPY FROM STDINまたはCOPY TO STDOUTを呼び出し、psqlクライアントからアクセス可能なファイルにデータをフェッチ/格納します。したがって、\ copyを使用する場合、ファイルのアクセシビリティとアクセス権はサーバーではなくクライアントに依存します。

アプリケーションプログラミング言語mayは、データのプッシュまたはフェッチもサポートしますが、一般に標準SQLステートメント内でCOPY FROM STDIN/TO STDOUTを使用することはできません。入力/出力を接続する方法がないためです。ストリーム。 PHPのPostgreSQLハンドラー(notPDO)には、非常に基本的な pg_copy_from および pg_copy_to PHP配列との間でコピーする関数が含まれます。大規模なデータセットに対して効率的である。

1242
IMSoP

いくつかの解決策があります。

1 psqlコマンド

psql -d dbname -t -A -F"," -c "select * from users" > output.csv

これには、ssh postgres@Host commandのようにSSH経由で使用できるという大きな利点があります。

2 postgres copyコマンド

COPY (SELECT * from users) To '/tmp/output.csv' With CSV;

3 psql対話式(またはしない)

>psql dbname
psql>\f ','
psql>\a
psql>\o '/tmp/output.csv'
psql>SELECT * from users;
psql>\q

それらはすべてスクリプトで使用できますが、私は#1が好きです。

4 pgadminしかしスクリプト化できません。

453
sorin

ターミナルで(dbに接続されている間に)cvsファイルに出力を設定します。

1)フィールド区切り文字を','に設定します。

\f ','

2)出力フォーマットを未整列に設定します。

\a

3)タプルのみを表示します。

\t

4)出力を設定します。

\o '/tmp/yourOutputFile.csv'

5)クエリを実行してください。

:select * from YOUR_TABLE

6)出力:

\o

あなたはそれからこの場所であなたのcsvファイルを見つけることができるでしょう:

cd /tmp

scpコマンドを使用してコピーするか、nanoを使用して編集します。

nano /tmp/yourOutputFile.csv
84
Marcin Wasiluk

all 特定のテーブルのカラムとヘッダを一緒に見たい場合は、

COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;

これは、ほんの少し簡単です。

COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;

これは、私の知る限りでは等価です。

34
benjwadams

CSVエクスポート統合

この情報はあまりよく表されていません。これを導出する必要があるのはこれが2回目であるため、これをここに置いて、他に何もない場合を思い出させます。

本当にこれを行う最良の方法(postgresからCSVを取得する)は、COPY ... TO STDOUTコマンドを使用することです。あなたはここの答えに示されている方法でそれをしたくないのですが。コマンドを使用する正しい方法は次のとおりです。

COPY (select id, name from groups) TO STDOUT WITH CSV HEADER

コマンドを1つだけ覚えてください!

Sshでの使用に最適です:

$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv

Ssh上のdocker内での使用に最適です:

$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv

ローカルマシンでも素晴らしいです:

$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv

または、ローカルマシンのdocker内?

docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv

または、kubernetesクラスター、Docker、HTTPS経由??:

kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv

とても多用途で、多くのコンマ!

あなたもですか?

はい、私はしました、ここに私のメモがあります:

COPYses

/copyを使用すると、psqlコマンドを実行しているすべてのシステムで、それを実行しているユーザーとして、ファイル操作を効果的に実行します 1 。リモートサーバーに接続する場合は、psqlを実行しているシステム上のデータファイルをリモートサーバーとの間で簡単にコピーできます。

COPYは、バックエンドプロセスのユーザーアカウント(デフォルトのpostgres)としてサーバー上でファイル操作を実行し、ファイルパスとパーミッションがチェックされ、それに応じて適用されます。 TO STDOUTを使用している場合、ファイルのアクセス許可チェックはバイパスされます。

最終的に結果のCSVを常駐させるシステムでpsqlが実行されていない場合、これらのオプションは両方とも後続のファイル移動を必要とします。私の経験では、これはほとんどの場合、リモートサーバーで作業する場合の最も可能性の高いケースです。

単純なCSV出力用にリモートシステムへのsshを介したTCP/IPトンネルのようなものを構成するのはより複雑ですが、他の出力形式(バイナリ)の場合、ローカル接続を実行してトンネル接続で/copypsql。同様に、大規模なインポートでは、ソースファイルをサーバーに移動し、COPYを使用することが、おそらく最高のパフォーマンスオプションです。

PSQLパラメーター

Psqlパラメータを使用すると、CSVのように出力をフォーマットできますが、ページャーを無効にしてヘッダーを取得しないことを忘れないようにするなどの欠点があります。

$ psql -P pager=off -d mydb -t -A -F',' -c 'select * from groups;'
2,Technician,Test 2,,,t,,0,,                                                                                                                                                                   
3,Truck,1,2017-10-02,,t,,0,,                                                                                                                                                                   
4,Truck,2,2017-10-02,,t,,0,,

その他のツール

いいえ、ツールをコンパイルまたはインストールせずに、サーバーからCSVを取得したいだけです。

23
joshperry

エラーメッセージが表示されたので、\ COPYを使用する必要がありました。

ERROR:  could not open file "/filepath/places.csv" for writing: Permission denied

だから私は使用しました:

\Copy (Select address, Zip  From manjadata) To '/filepath/places.csv' With CSV;

そしてそれは機能している

22
maudulus

psqlはあなたのためにこれを行うことができます:

edd@ron:~$ psql -d beancounter -t -A -F"," \
                -c "select date, symbol, day_close " \
                   "from stockprices where symbol like 'I%' " \
                   "and date >= '2009-10-02'"
2009-10-02,IBM,119.02
2009-10-02,IEF,92.77
2009-10-02,IEV,37.05
2009-10-02,IJH,66.18
2009-10-02,IJR,50.33
2009-10-02,ILF,42.24
2009-10-02,INTC,18.97
2009-10-02,IP,21.39
edd@ron:~$

ここで使用されているオプションについてはman psqlを参照してください。

16

私はAWS Redshiftに取り組んでいます。これはCOPY TO機能をサポートしていません。

私のBIツールはタブ区切りのCSVをサポートしているので、私は以下を使用しました:

 psql -h dblocation -p port -U user -d dbname -F $'\t' --no-align -c "SELECT * FROM TABLE" > outfile.csv
11
calcsam

PgAdmin IIIでは、クエリウィンドウからファイルにエクスポートするオプションがあります。メインメニューにはQuery - > Execute to fileか同じことをするボタンがあります(ただクエリを実行する普通の緑色の三角形とは対照的に青いフロッピーディスクのある緑色の三角形です)。クエリウィンドウからクエリを実行していない場合は、IMSoPが提案したことを実行し、copyコマンドを使用します。

11
Amanda Nyren

新バージョン - psql 12 - は--csvをサポートします。

psql - devel

--csv

CSV(カンマ区切り)出力モードに切り替えます。これは \pset format csv と同じです。


csv_fieldsep

CSV出力形式で使用されるフィールド区切り文字を指定します。区切り文字がフィールドの値にある場合、そのフィールドは標準のCSV規則に従って二重引用符で囲まれて出力されます。デフォルトはカンマです。

使用法:

psql -c "SELECT * FROM pg_catalog.pg_tables" --csv  postgres

psql -c "SELECT * FROM pg_catalog.pg_tables" --csv -P csv_fieldsep='^'  postgres

psql -c "SELECT * FROM pg_catalog.pg_tables" --csv  postgres > output.csv
7
Lukasz Szozda

psql2csvパターンをカプセル化する COPY query TO STDOUT と呼ばれる小さなツールを書いたので、正しいCSVが得られます。そのインターフェースはpsqlに似ています。

psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY

問い合わせは、存在する場合はSTDINの内容、または最後の引数であると見なされます。これらを除いて、他のすべての引数はpsqlに転送されます。

-h, --help           show help, then exit
--encoding=ENCODING  use a different encoding than UTF8 (Excel likes LATIN1)
--no-header          do not output a header
6
fphilipe

私はいくつかのことを試みましたが、それらのうちのいくつかは私にヘッダの詳細を含む希望のCSVを与えることができませんでした。

これは私のために働いたものです。

psql -d dbame -U username \
  -c "COPY ( SELECT * FROM TABLE ) TO STDOUT WITH CSV HEADER " > \
  OUTPUT_CSV_FILE.csv
5
pyAddict

もっと長い問い合わせをしていてpsqlを使いたい場合は、その問い合わせをファイルに書き出して次のコマンドを使います。

psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
5
Andres Kull

列名がHEADERのCSVファイルをダウンロードするには、次のコマンドを使用します。

Copy (Select * From tableName) To '/tmp/fileName.csv' With CSV HEADER;
2
murli

Webブラウザのデータベースクライアントである JackDB は、これを本当に簡単にします。特にHerokuを使っている人は.

これにより、リモートデータベースに接続してそれらに対してSQLクエリを実行できます。

出典 jackdb-heroku http://static.jackdb.com/assets/img/blog/jackdb-heroku-oauth-connect.gif


DBに接続したら、クエリを実行してCSVまたはTXTにエクスポートできます(右下参照)。


jackdb-export

注: JackDBと提携しているわけではありません。私は現在彼らの無料サービスを利用しており、それは素晴らしい製品だと思います。

1
Dennis

DataGrip 、JetBrainsのデータベースIDEを強くお勧めします。 SQLクエリをCSVファイルにエクスポート で、sshトンネリングを簡単に設定できます。ドキュメントが「結果セット」に言及する場合、コンソールのSQLクエリによって返される結果を意味します。

私はDataGripとは関係ありません。ただ製品が大好きです!

0
skeller88