回答:
結果のファイルをサーバーまたはクライアントのどちらに置きますか?
再利用や自動化が簡単なものが必要な場合は、Postgresqlの組み込みのCOPYコマンドを使用できます。例えば
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
このアプローチは完全にリモートサーバーで実行されます -ローカルPCに書き込むことはできません。また、Postgresはそのマシンのローカルファイルシステムで厄介なことを行うのを止めることができないため、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はCOPY FROM STDINまたはCOPY TO STDOUTを呼び出してから、psqlクライアントがアクセスできるファイルにデータをフェッチ/保存します。したがって、\ copyを使用すると、ファイルのアクセス可能性とアクセス権はサーバーではなくクライアントに依存します。
アプリケーションプログラミング言語もデータのプッシュまたはフェッチをサポートしている場合がありますが、入力/出力ストリームを接続する方法がないため、標準のSQLステートメント内でCOPY FROM STDIN
/を使用することはできませんTO STDOUT
。PHPのPostgreSQLハンドラー(PDOではない)には、PHP配列pg_copy_from
との間pg_copy_to
でコピーを行う非常に基本的な関数が含まれています。
\copy
動作します-パスはクライアントからの相対パスであり、セミコロンは必要ありません/許可されていません。私の編集を参照してください。
\copy
ワンライナーである必要があるようです。そのため、SQLを希望どおりにフォーマットし、コピー/関数を配置するだけの美しさは得られません。
\copy
特別なメタコマンドです。pgAdminなどの他のクライアントでは機能しません。彼らはおそらく、この作業を行うためのグラフィカルウィザードなどの独自のツールを持っています。psql
いくつかの解決策があります:
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
COPY
または\copy
正しくハンドル(標準CSV形式に変換)に近づきます。これは?
ヘッダーとともに特定のテーブルのすべての列に興味がある場合は、
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
、ファイルのアクセス権チェックはバイパスされます。
psql
結果のCSVを最終的に常駐させたいシステムでが実行されていない場合、これらのオプションの両方で後続のファイル移動が必要です。これは、私の経験では、ほとんどの場合、ほとんどがリモートサーバーで作業する場合です。
単純な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を取り出したいだけです。
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
ここで使用されるオプションのヘルプについては、を参照してください。
新しいバージョン-psql 12-がサポートされ--csv
ます。
--csv
CSV(コンマ区切り値)出力モードに切り替えます。これは、\ pset形式の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
JetBrainsによるデータベースIDEであるDataGripを強くお勧めします。SQLクエリをCSVファイルにエクスポートできますに SSHトンネリングを簡単に設定できます。ドキュメントが「結果セット」に言及する場合、それらはコンソールのSQLクエリによって返される結果を意味します。
私はDataGripに関連付けられていません。製品が大好きです。
WebブラウザーのデータベースクライアントであるJackDBは、これを非常に簡単にします。特にHerokuを使用している場合。
リモートデータベースに接続し、SQLクエリを実行できます。
ソース
(ソース:jackdb.com)
DBが接続されたら、クエリを実行してCSVまたはTXTにエクスポートできます(右下を参照)。
注:私はJackDBとは一切関係ありません。私は現在彼らの無料サービスを利用しており、素晴らしい製品だと思います。
@ 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、またはその他の一般的なデータ形式で保存できます。TOAD for Postgres、TOAD for SQL Server、またはToad for Oracleの実行可能なFOSSライバルです。
私はDBeaverとは関係ありません。価格と機能は気に入っていますが、DBeaver / Eclipseアプリケーションをさらに開き、分析ウィジェットをDBeaver / Eclipseに簡単に追加できるようにしたいと思います。ユーザーが年間サブスクリプションに料金を支払ってグラフやチャートを直接作成する必要はありません。アプリケーション。私のJavaコーディングスキルは錆びており、Eclipseウィジェットの構築方法を再学習するのに何週間もかかるような気がしません。DBeaverがサードパーティのウィジェットをDBeaver Community Editionに追加する機能を無効にしていることに気づくだけです。
DBeaverのCommunity Editionに追加する分析ウィジェットを作成する手順について、DBeaverユーザーは洞察力がありますか?
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'