PostgresテーブルをJSONとしてエクスポート


35

postgresのテーブルデータをjsonとしてファイルにエクスポートする方法はありますか?出力は次のように1行ずつ必要です。

{'id':1,'name':'David'}
{'id':2,'name':'James'}
...

編集:postgresバージョン:9.3.4

回答:


48

およびの基本的な紹介をご覧ください。PostgreSQLJSON

また、PostgreSQLのドキュメントは非常に優れているため、こちらで試してくださいpretty_boolオプションをご覧ください。

元の質問は、「postgresテーブルデータをエクスポートする方法はありますかJSON」でした。この形式で欲しかった

{'id':1,'name':'David'}
{'id':2,'name':'James'}
...

の実行中のインスタンスがPostgreSQLなかったため、9.4をダウンロード、コンパイル、およびインストールしました。

これに答えるために、私は最初にCREATEテーブル(フレッド)を編集しました

CREATE TABLE fred (mary INT, jimmy INT, paulie VARCHAR(20));

INSERT INTO fred VALUES (2,    43, 'asfasfasfd'      );
INSERT INTO fred VALUES (3,   435, 'ererere'         );
INSERT INTO fred VALUES (6, 43343, 'eresdfssfsfasfae');

次に、確認するには:

test=# select * from fred;

 mary | jimmy |      paulie      
------+-------+------------------
    2 |    43 | asfasfasfd
    3 |   435 | ererere
    6 | 43343 | eresdfssfsfasfae

次に、このコマンドを発行しました

test=# COPY (SELECT ROW_TO_JSON(t) 
test(# FROM (SELECT * FROM fred) t) 
test-# TO '/paulstuff/sware/db/postgres/inst/myfile';
COPY 3
test=# 

次にpsqlを終了し、ファイルmyfileをリストしました。

test=# \q
[pol@polhost inst]$ more myfile 
{"mary":2,"jimmy":43,"paulie":"asfasfasfd"}
{"mary":3,"jimmy":435,"paulie":"ererere"}
{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}
[pol@polhost inst]$

(からの出力を試すことができます

COPY (SELECT ROW_TO_JSON(t, TRUE)  -- <-- Note addition of "TRUE" here!

お暇な時に)。

@ offby1は、出力が(OPの質問に対応している間)正しくないことを指摘しましたJSON。@EvanCarrollは\o、これもファイルへの出力方法であると指摘したので、このステートメントでこれら2つの解決策を組み合わせました(ここからの助けを借り)。

test=# \o out.json
test=# SELECT array_to_json(array_agg(fred), FALSE) AS ok_json FROM fred;
                                     -- <-- "TRUE" here will produce plus
                                        ("+) signs in the output. "FALSE"
                                        is the default anyway.
test=# \o

与える:

[pol@polhost inst]$ more out.json 
                                                                   ok_json                                                                    
----------------------------------------------------------------------------------------------------------------------------------------------
 [{"mary":2,"jimmy":43,"paulie":"asfasfasfd"},{"mary":3,"jimmy":435,"paulie":"ererere"},{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}]
(1 row)
[pol@polhost inst]$ 

FINALLY、バックスラッシュ(そこにある\彼のポストに@AdamGentによって示唆した)問題が。これは少しトリッキーだったが、それはあるポストクエリ処理に頼ることなく可能。Voilà:

INSERT INTO fred VALUES (35, 5, 'wrew\sdfsd');
INSERT INTO fred VALUES (3, 44545, '\sdfs\\\sfs\\gf');

したがって、REGEXP_REPLACEを使用すると(キャスト:: TEXTに注意)、余分なブラックスラッシュが削除されます。

test=# \o slash.json
test=# SELECT REGEXP_REPLACE(ROW_TO_JSON(t)::TEXT, '\\\\', '\\', 'g') 
test=# FROM (SELECT * FROM fred) AS t;  -- I found that using a CTE was helpful for legibility
test=# \o
test=# \q

与える:

[pol@polhost inst]$ more slash.json 
                    regexp_replace                    
------------------------------------------------------
 {"mary":2,"jimmy":43,"paulie":"asfasfasfd"}
 {"mary":3,"jimmy":435,"paulie":"ererere"}
 {"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}
 {"mary":35,"jimmy":5,"paulie":"wrew\sdfsd"}
 {"mary":3,"jimmy":44545,"paulie":"\sdfs\\\sfs\\gf"}
(5 rows)
[pol@polhost inst]$ 

(ps @Zoltánのコメントは-これはバージョンの問題かもしれません-再現できません!)。


2
それはまさに元のポスターが望んでいたもののようです。ただし、各行は適切なJSON ですが、行を区切るコンマとそれらを囲む角括弧がないため、行のコレクションは適切ではありません。
-offby1

3
列に何かがある場合、これは機能しませんbackslash !!!! COPY docは、backslash文字に対して特別なこと(別のバックスラッシュを追加するなど)を行うため、慎重に読んでください。
アダム・ゲント

バックスラッシュ問題解決するには、以下のREAD @AdamGentの答え
手のひらを顔に当てる

1
だから... 2017年とCOPYコマンドでJSONエクスポートする方法はありませんPostgreSQL ?? CSVオプション、TXTオプションがあります... JSONオプションはありませんか?
ピータークラウス

1
@Véraceに感謝します。申し訳ありませんが、複雑なJSONbでCOPYをテストしましたが、処理されたJSONは「適切なJSON」で問題ありませんでした。
ピータークラウス

13

あなたが使用している場合はpsql、次に使用する理由はありません\COPYすべてでは。

\t
\a
\o file.json
SELECT row_to_json(r) FROM my_table AS r;

これは、PostGISを使用してデータベースからpng / jpgs / tifsを取得して簡単なテストを行い、PostgreSQLの拡張子を持つスクリプトファイルを生成するために使用するのと同じ方法です。


すばらしいです!通常のCOPYコマンド「相対パスを許可しない」のように、psql-native-commandsは相対パスにコピーする最も簡単な方法です!PS:相対パスで実際のCOPYコマンドを使用する「ターミナル方法」があります。こちらを参照してくださいpsql -h remotehost -d remote_mydb -U myuser -c "COPY (SELECT '{\"x\":1,\"y\":[\"a\",2]}'::json AS r) TO STDOUT" > ./relative_path/file.csv
ピータークラウス

6

私にとって@Véraceの答えは、列名を保持しませんでしたが、割り当てられたデフォルトの名前(f1f2など)の代わりに。JSON拡張機能付きのPostgreSQL 9.1を使用しています

テーブル全体をエクスポートする場合、サブクエリは不要です。さらに、これにより列名維持されます。次のクエリを使用しました。

COPY (SELECT row_to_json(t) FROM fred as t) to '/home/pol/Downloads/software/postgres/inst/myfile';

列名を維持しました!CREATE TABLE fred (mary INT, jimmy INT, paulie VARCHAR(20));結果:{"mary":2,"jimmy":43,"paulie":"asfasfasfd"}-フィールド名はマリア、ジミー、ポーリー...とあり、NOTf1f2。、など)...
Vérace

5

Veraceの回答に特別な警告を追加しますバックスラッシュ文字を含むテキスト列がある場合は、出力されたJSONファイルで後処理を行う必要があります\

そうしないと、良くても重複(\-> \\)し、最悪の場合は完全に無効なJSONになります:

この:

{ "f1" : "crap\""}.

になる

{ "f1" : "crap\\""}.

見た目は問題ありませんが、完全に無効なJSONです。

\\into \をsedに置き換えることができます。

sed -i -e 's/\\\\/\\/g' PG_OUT_JSON_FILE.json

Postgres COPYから彼らがそれについて言及することについて回っているところ:

現在、COPY TOは8進数または16進数のバックスラッシュシーケンスを発行しませんが、これらの制御文字に対して上記の他のシーケンスを使用します。上記の表に記載されていない他のバックスラッシュ文字は、それ自体を表すものと見なされます。ただし、バックスラッシュを不必要に追加すると、データ終了マーカー(。)またはヌル文字列(デフォルトでは\ N)に一致する文字列が誤って生成される可能性があるため、注意してください。これらの文字列は、他のバックスラッシュ処理が行われる前に認識されます。

COPYデータを生成するアプリケーションは、データの改行と復帰をそれぞれ\ nおよび\ rシーケンスに変換することを強くお勧めします。現在、バックスラッシュとキャリッジリターンでデータキャリッジリターンを表し、バックスラッシュと改行でデータ改行を表すことができます。ただし、これらの表現は将来のリリースで受け入れられなくなる可能性があります。また、COPYファイルが異なるマシン間で転送された場合(たとえば、UnixからWindowsへ、またはその逆)、破損に対して非常に脆弱です。

COPY TOは、各行をUnixスタイルの改行( "\ n")で終了します。Microsoft Windowsで実行されているサーバーは、代わりにキャリッジリターン/改行( "\ r \ n")を出力しますが、サーバーファイルへのCOPYのみです。プラットフォーム間の一貫性のために、COPY TO STDOUTは、サーバープラットフォームに関係なく、常に「\ n」を送信します。COPY FROMは、改行、キャリッジリターン、またはキャリッジリターン/改行で終わる行を処理できます。バックスラッシュのない改行またはデータとして意図されたキャリッジリターンによるエラーのリスクを減らすために、COPY FROMは、入力の行末がすべて異なる場合に文句を言います。


私は答えでこれを扱った-あなたがそれが満足できることを願っています。そうでない場合は、お知らせください。
Vérace


0

これは、有効なJSON(オブジェクトの配列)を出力する唯一の方法です

\t
\a
\o data.json
select json_agg(t) FROM (SELECT * from table) t;

ソース

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.