Postgres 테이블을 json으로 내보내기


34

postgres 테이블 데이터를 JSON으로 파일로 내보내는 방법이 있습니까? 다음과 같이 출력을 한 줄씩해야합니다.

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

편집 : postgres 버전 : 9.3.4

답변:


47

및 에 대한 기본 소개를 보려면 여기 를 시도 하십시오 .PostgreSQLJSON

또한 PostgreSQL 설명서는 꽤 좋으므로 여기서 사용해보십시오 . pretty_bool옵션을 확인하십시오 .

원래 질문은 "postgres 테이블 데이터를 JSON" 로 내보내는 방법이 있습니까? "였습니다. 이 형식으로 원했습니다

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

실행중인 인스턴스가 PostgreSQL없으므로 9.4를 다운로드, 컴파일 및 설치했습니다.

이에 답하기 위해 먼저 CREATE테이블을 편집했습니다 (fred)

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파일로 출력하는 방법 이라고 지적 했으므로이 문장 에서이 두 가지 문제에 대한 솔루션을 결합했습니다 ( 여기의 도움으로 ).

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]$ 

마지막으로 , \@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
이 것 NOT 당신이 어떤 경우 작동 backslash당신의 열의를 !!!! COPY 문서는 backslash다른 백 슬래시 추가와 같이 문자에 대한 특별한 작업을 수행하므로주의해서 읽으십시오 .
Adam Gent

백 슬래시 문제를 해결하기 위해 아래 @AdamGent의 답변을 읽으십시오
FacePalm

1
그래서 ... 2017 년과 COPY 명령 PostgreSQL을 사용하여 JSON 을 내보낼 방법이 없습니다 ?? CSV 옵션, TXT 옵션이 있습니다. JSON 옵션이 아닌 이유는 무엇입니까?
피터 크라우스

1
@ Vérace에게 감사합니다. 그리고 죄송합니다. 이제 복잡한 JSONb로 COPY를 테스트했으며 진행된 JSON은 "적절한 JSON"으로 훌륭했습니다!
피터 크라우스

12

사용하고 있다면 psql전혀 사용할 이유가 없습니다 \COPY.

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

빠른 테스트를 위해 PostGIS를 사용하여 데이터베이스에서 png / jpgs / tif를 가져오고 PostgreSQL 확장자를 가진 스크립트 파일을 생성하는 데 사용하는 것과 같은 방법입니다.


큰! 일반적인 COPY 명령 "상대 경로를 허용하지 않음" 과 같이 psql-native-commands는 상대 경로에 복사 하는 가장 쉬운 방법입니다 ! 추신 : 상대 경로와 함께 실제 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
피터 크라우스

5

나를 위해 @ Vérace의 대답은 열 이름을 유지하지 않았지만, 할당 된 기본 이름 ( f1, f2, 등) 대신. 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"}- 필드의 이름은 메리, 지미, 폴리 ... 그리고 있습니다 NOT ( f1, f2., 등) ...
Vérace

5

Verace의 답변에 특별한 경고를 추가 할 입니다. 백 슬래시 문자가있는 텍스트 열이있는 경우 출력 된 JSON 파일에서 사후 처리를 수행해야합니다\ .

그렇지 않으면 최상의 경우 중복되고 ( \-> \\) 완전히 잘못된 JSON이됩니다.

이:

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

된다

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

잘 보이지만 완전히 잘못된 JSON입니다.

을 sed \\로 바꿀 수 있습니다 \.

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

에서 포스트 그레스 COPY 그들은 사방을 언급 여기서

현재 COPY TO는 8 진수 또는 16 진수 백 슬래시 시퀀스를 방출하지 않지만 해당 제어 문자에 대해 위에 나열된 다른 시퀀스를 사용합니다. 위 표에서 언급되지 않은 다른 백 슬래시 문자는 자체를 나타내는 것으로 간주됩니다. 그러나 백 슬래시를 불필요하게 추가하면 실수로 데이터 끝 표시 (.) 또는 null 문자열 (기본적으로 \ 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.