PostgreSQLデータベースからCSVファイルにPL/pgSQL出力を保存する最も簡単な方法は何ですか?
クエリを実行するpgAdminIIIおよびPSQLプラグインでPostgreSQL8.4を使用しています。
PostgreSQLデータベースからCSVファイルにPL/pgSQL出力を保存する最も簡単な方法は何ですか?
クエリを実行するpgAdminIIIおよびPSQLプラグインでPostgreSQL8.4を使用しています。
結果のファイルをサーバーに配置しますか、それともクライアントに配置しますか?
再利用や自動化が簡単なものが必要な場合は、Postgresqlに組み込まれているCOPYコマンドを使用できます。例えば
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
このアプローチは完全にリモートサーバー上で実行されます-ローカルPCに書き込むことはできません。また、Postgresの「スーパーユーザー」(通常は「root」と呼ばれます)として実行する必要があります。これは、Postgresがそのマシンのローカルファイルシステムで厄介なことをするのを止めることができないためです。
これは、実際にはスーパーユーザーとして接続する必要があるという意味ではありません(自動化は別の種類のセキュリティリスクになります)。オプションを使用してSECURITY DEFINER
CREATE FUNCTION
、スーパーユーザーであるかのように実行される関数を作成できるためです。
重要な部分は、セキュリティをバイパスするだけでなく、追加のチェックを実行する関数があることです。したがって、必要なデータを正確にエクスポートする関数を記述したり、さまざまなオプションを受け入れることができる関数を記述したりできます。厳格なホワイトリストを満たします。次の2つを確認する必要があります。
GRANT
ますが、関数は現在スーパーユーザーとして実行されているため、通常は「範囲外」のテーブルに完全にアクセスできます。おそらく、誰かに関数を呼び出させて「users」テーブルの最後に行を追加させたくないでしょう…</ li>
厳しい条件を満たすファイルやテーブルをエクスポート(またはインポート)する関数の例を含め、このアプローチを拡張したブログ投稿を書きました。
もう1つのアプローチは、クライアント側、つまりアプリケーションまたはスクリプトでファイル処理を行うことです。Postgresサーバーは、コピー先のファイルを知る必要はありません。データを吐き出し、クライアントがそれをどこかに置きます。
この基本的な構文はCOPY TO STDOUT
コマンドであり、pgAdminなどのグラフィカルツールがそれを素敵なダイアログにラップします。
psql
コマンドラインクライアントには、と呼ばれる特別な「メタコマンド」があります。\copy
これは「実際の」と同じオプションをすべて使用しますCOPY
が、クライアント内で実行されます。
\copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER
;
SQLコマンドとは異なり、メタコマンドは改行で終了するため、終了はありません。
ドキュメントから:
COPYをpsql命令\copyと混同しないでください。\ copyは、COPYFROMSTDINまたはCOPYTOSTDOUTを呼び出してから、psqlクライアントにアクセス可能なファイルにデータをフェッチ/保存します。したがって、\ copyを使用する場合、ファイルのアクセス可能性とアクセス権はサーバーではなくクライアントに依存します。
アプリケーションプログラミング言語でもデータのプッシュまたはフェッチがサポートされている場合がありますが、入出力ストリームを接続する方法がないため、通常、標準のSQLステートメント内でCOPY FROM STDIN
/を使用することはできません。TO STDOUT
PHPのPostgreSQLハンドラー(PDOではない)には、PHP配列との間でコピーする非常に基本的な関数が含まれているため、大規模なデータセットには効率的でない場合がありますpg_copy_from
。pg_copy_to
いくつかの解決策があります:
psql
コマンドpsql -d dbname -t -A -F"," -c "select * from users" > output.csv
これには、SSH経由で使用できるという大きな利点がありますssh postgres@host command
。
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
この情報はあまりよく表されていません。これを導き出す必要があるのはこれが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
システムでファイル操作が効果的に実行されます1。リモートサーバーに接続する場合、実行中のシステム上のデータファイルをリモートサーバーとの間で簡単にコピーできます。psql
psql
COPY
バックエンドプロセスのユーザーアカウント(デフォルトpostgres
)としてサーバー上でファイル操作を実行し、ファイルパスとアクセス許可がチェックされ、それに応じて適用されます。を使用する場合TO STDOUT
、ファイルのアクセス許可チェックはバイパスされます。
psql
結果のCSVを最終的に常駐させたいシステムでが実行されていない場合、これらのオプションは両方とも後続のファイル移動を必要とします。私の経験では、これは主にリモートサーバーで作業する場合に最も可能性の高いケースです。
/copy
単純なCSV出力用にssh経由でリモートシステムへのTCP/IPトンネルのようなものを構成するのはより複雑ですが、他の出力形式(バイナリ)の場合は、トンネル接続を介してローカルを実行する方がよい場合があります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 table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
これは少し簡単です
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
私の知る限り、これは同等です。
新しいバージョン(psql 12)はをサポートし--csv
ます。
--csv
CSV(カンマ区切り値)出力モードに切り替えます。これは、 \ psetformatcsvと同等です。
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
エラーメッセージが表示されたため、\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
ここで使用されるオプションのヘルプについては、を参照してください。
この機能をサポートしていないAWSRedshiftに取り組んでい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には、クエリウィンドウからファイルにエクスポートするオプションがあります。メインメニューには、[クエリ]-> [ファイルに実行]があります。または、同じことを行うボタンがあります(クエリを実行するだけの緑色の三角形とは対照的に、青色のフロッピーディスクが付いた緑色の三角形です)。クエリウィンドウからクエリを実行していない場合は、IMSoPが提案したことを実行し、copyコマンドを使用します。
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.com)
DBが接続されると、クエリを実行してCSVまたはTXTにエクスポートできます(右下を参照)。
注:私はJackDBとは一切関係がありません。私は現在彼らの無料サービスを利用していて、それは素晴らしい製品だと思います。
import json
cursor = conn.cursor()
qry = """ SELECT details FROM test_csvfile """
cursor.execute(qry)
rows = cursor.fetchall()
value = json.dumps(rows)
with open("/home/asha/Desktop/Income_output.json","w+") as f:
f.write(value)
print 'Saved to File Successfully'
@ skeller88のリクエストにより、すべての回答を読んでいない人に迷子にならないように、コメントを回答として再投稿しています...
DataGripの問題は、ウォレットにグリップがかかることです。無料ではありません。dbeaver.ioでDBeaverのコミュニティエディションをお試しください。これは、SQLプログラマー、DBA、およびアナリスト向けのFOSSマルチプラットフォームデータベースツールであり、MySQL、PostgreSQL、SQLite、Oracle、DB2、SQL Server、Sybase、MS Access、Teradata、Firebird、Hive、Prestoなどの一般的なすべてのデータベースをサポートします。
DBeaver Community Editionを使用すると、データベースに接続し、クエリを発行してデータを取得し、結果セットをダウンロードしてCSV、JSON、SQL、またはその他の一般的なデータ形式に保存するのが簡単になります。これは、Postgresの場合はTOAD、SQL Serverの場合はTOAD、Oracleの場合はToadの実行可能なFOSS競合企業です。
私はDBeaverとは何の関係もありません。価格と機能は気に入っていますが、ユーザーがグラフやチャートを直接作成するために年間サブスクリプションの料金を支払う必要はなく、DBeaver / Eclipseアプリケーションをさらに開き、分析ウィジェットをDBeaver/Eclipseに簡単に追加できるようにしたいと思います。アプリケーション。私のJavaコーディングスキルは錆びており、Eclipseウィジェットの構築方法を再学習するのに何週間もかかる気はありませんが、DBeaverがサードパーティのウィジェットをDBeaverCommunityEditionに追加する機能を無効にしていることに気づきました。
DBeaverユーザーは、DBeaverのCommunity Editionに追加する分析ウィジェットを作成する手順について洞察を持っていますか?