PostgreSQLデータベースからのPL/pgSQL出力をCSVファイルに保存する最も簡単な方法は何ですか?
私はPostgreSQL 8.4をpgAdmin IIIとPSQLプラグインと共に使っています。
結果のファイルをサーバーまたはクライアントに作成しますか?
簡単に再利用したり自動化したい場合は、Postgresqlの組み込みの COPY コマンドを使用できます。例えば.
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',';
このアプローチは完全にリモートサーバーで実行されます-ローカルPCに書き込むことができません。 Postgresは、そのマシンのローカルファイルシステムで厄介なことを行うのを止めることができないため、Postgresの「スーパーユーザー」(通常は「ルート」と呼ばれます)として実行する必要もあります。
を使用してSECURITY DEFINER
オプションをCREATE FUNCTION
を使用してスーパーユーザーであるかのように実行します。
重要な部分は、セキュリティをバイパスするだけでなく、関数が追加のチェックを実行することです-したがって、必要な正確なデータをエクスポートする関数を記述したり、さまざまなオプションを受け入れることができるものを記述したりできます厳格なホワイトリストを満たします。次の2つのことを確認する必要があります。
GRANT
sによって定義されますが、関数は現在スーパーユーザーとして実行されているため、通常「範囲外」にあるテーブルには完全にアクセスできます。誰かがあなたの関数を呼び出して「ユーザー」テーブルの最後に行を追加できるようにしたくないでしょう。私は このアプローチを拡張するブログ投稿を書きました 厳密な条件を満たすファイルとテーブルをエクスポート(またはインポート)する関数の例を含む。
もう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配列との間でコピーする関数が含まれます。大規模なデータセットに対して効率的である。
いくつかの解決策があります。
psql
コマンドpsql -d dbname -t -A -F"," -c "select * from users" > output.csv
これには、ssh postgres@Host command
のようにSSH経由で使用できるという大きな利点があります。
copy
コマンドCOPY (SELECT * from users) To '/tmp/output.csv' With CSV;
>psql dbname
psql>\f ','
psql>\a
psql>\o '/tmp/output.csv'
psql>SELECT * from users;
psql>\q
それらはすべてスクリプトで使用できますが、私は#1が好きです。
ターミナルで(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
all 特定のテーブルのカラムとヘッダを一緒に見たい場合は、
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
これは、ほんの少し簡単です。
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
これは、私の知る限りでは等価です。
この情報はあまりよく表されていません。これを導出する必要があるのはこれが2回目であるため、これをここに置いて、他に何もない場合を思い出させます。
本当にこれを行う最良の方法(postgresからCSVを取得する)は、COPY ... TO STDOUT
コマンドを使用することです。あなたはここの答えに示されている方法でそれをしたくないのですが。コマンドを使用する正しい方法は次のとおりです。
COPY (select id, name from groups) TO STDOUT WITH CSV HEADER
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
とても多用途で、多くのコンマ!
はい、私はしました、ここに私のメモがあります:
/copy
を使用すると、psql
コマンドを実行しているすべてのシステムで、それを実行しているユーザーとして、ファイル操作を効果的に実行します 1 。リモートサーバーに接続する場合は、psql
を実行しているシステム上のデータファイルをリモートサーバーとの間で簡単にコピーできます。
COPY
は、バックエンドプロセスのユーザーアカウント(デフォルトのpostgres
)としてサーバー上でファイル操作を実行し、ファイルパスとパーミッションがチェックされ、それに応じて適用されます。 TO STDOUT
を使用している場合、ファイルのアクセス許可チェックはバイパスされます。
最終的に結果のCSVを常駐させるシステムでpsql
が実行されていない場合、これらのオプションは両方とも後続のファイル移動を必要とします。私の経験では、これはほとんどの場合、リモートサーバーで作業する場合の最も可能性の高いケースです。
単純なCSV出力用にリモートシステムへのsshを介したTCP/IPトンネルのようなものを構成するのはより複雑ですが、他の出力形式(バイナリ)の場合、ローカル接続を実行してトンネル接続で/copy
psql
。同様に、大規模なインポートでは、ソースファイルをサーバーに移動し、COPY
を使用することが、おそらく最高のパフォーマンスオプションです。
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を取得したいだけです。
エラーメッセージが表示されたので、\ 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;
そしてそれは機能している
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
を参照してください。
私は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
PgAdmin IIIでは、クエリウィンドウからファイルにエクスポートするオプションがあります。メインメニューにはQuery - > Execute to fileか同じことをするボタンがあります(ただクエリを実行する普通の緑色の三角形とは対照的に青いフロッピーディスクのある緑色の三角形です)。クエリウィンドウからクエリを実行していない場合は、IMSoPが提案したことを実行し、copyコマンドを使用します。
新バージョン - psql 12 - は--csv
をサポートします。
--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
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
私はいくつかのことを試みましたが、それらのうちのいくつかは私にヘッダの詳細を含む希望のCSVを与えることができませんでした。
これは私のために働いたものです。
psql -d dbame -U username \
-c "COPY ( SELECT * FROM TABLE ) TO STDOUT WITH CSV HEADER " > \
OUTPUT_CSV_FILE.csv
もっと長い問い合わせをしていてpsqlを使いたい場合は、その問い合わせをファイルに書き出して次のコマンドを使います。
psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
列名がHEADERのCSVファイルをダウンロードするには、次のコマンドを使用します。
Copy (Select * From tableName) To '/tmp/fileName.csv' With CSV HEADER;
Webブラウザのデータベースクライアントである JackDB は、これを本当に簡単にします。特にHerokuを使っている人は.
これにより、リモートデータベースに接続してそれらに対してSQLクエリを実行できます。
出典 jackdb-heroku http://static.jackdb.com/assets/img/blog/jackdb-heroku-oauth-connect.gif
DBに接続したら、クエリを実行してCSVまたはTXTにエクスポートできます(右下参照)。
注: JackDBと提携しているわけではありません。私は現在彼らの無料サービスを利用しており、それは素晴らしい製品だと思います。
DataGrip 、JetBrainsのデータベースIDEを強くお勧めします。 SQLクエリをCSVファイルにエクスポート で、sshトンネリングを簡単に設定できます。ドキュメントが「結果セット」に言及する場合、コンソールのSQLクエリによって返される結果を意味します。
私はDataGripとは関係ありません。ただ製品が大好きです!