PostgreSQL의 PL / pgSQL 출력을 CSV 파일로 저장


답변:


1367

서버 나 클라이언트에서 결과 파일을 원하십니까?

서버 측

재사용하거나 자동화하기 쉬운 것을 원한다면 Postgresql의 내장 COPY 명령을 사용할 수 있습니다 . 예 :

Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;

이 방법은 전적으로 원격 서버에서 실행되며 로컬 PC에는 쓸 수 없습니다. 또한 Postgres는 해당 시스템의 로컬 파일 시스템에서 불쾌한 일을 멈출 수 없기 때문에 Postgres "슈퍼 유저"(일반적으로 "루트")로 실행해야합니다.

당신이 사용할 수 있기 때문에 실제로는 수퍼 유저로 연결되어 있어야 의미하지 않는다 (즉, 다른 종류의 보안 위험이 될 것 자동화) 하는 옵션을 함수 만들기 위해 당신은 슈퍼 유저 인 것처럼 실행을 .SECURITY DEFINERCREATE FUNCTION

중요한 부분은 함수가 보안을 우회하지 않고 추가 검사를 수행해야한다는 것입니다. 따라서 필요한 정확한 데이터를 내보내는 함수를 작성하거나 다양한 옵션을 허용하는 한 작성할 수 있습니다 엄격한 화이트리스트를 만나십시오. 두 가지를 확인해야합니다.

  1. 어떤 파일은 사용자가 디스크의 읽기 / 쓰기로 허용해야 하는가? 예를 들어이 디렉토리는 특정 디렉토리 일 수 있으며 파일 이름에 적합한 접두사 또는 확장자가 있어야합니다.
  2. 어떤 테이블 사용자가 데이터베이스에 읽기 / 쓰기 할 수 있어야한다? 이것은 일반적으로 GRANT데이터베이스에서 s 로 정의 되지만 함수는 이제 수퍼 유저로 실행되므로 일반적으로 "범위를 벗어난"테이블에 완전히 액세스 할 수 있습니다. 다른 사람이 함수를 호출하고 "사용자"테이블의 끝에 행을 추가하지 못하게하고 싶을 것입니다.

필자는 엄격한 조건을 충족하는 파일 및 테이블을 내보내거나 가져 오는 함수의 예를 포함 하여이 접근법을 확장하는 블로그 게시물을 작성 했습니다 .


고객 입장에서

다른 방법은 클라이언트 측 , 즉 응용 프로그램이나 스크립트에서 파일 처리수행하는 것 입니다. Postgres 서버는 어떤 파일을 복사하고 있는지 알 필요가 없으며 데이터를 뱉어 내고 클라이언트는 파일을 어딘가에 넣습니다.

이것에 대한 기본 구문은 COPY TO STDOUT명령이며 pgAdmin과 같은 그래픽 도구는 멋진 대화 상자로 감싸줍니다.

psql명령 줄 클라이언트 라는 특별한 "메타 명령"이 \copy"진짜"모든 같은 옵션을 소요 COPY하지만, 클라이언트 내에서 실행됩니다 :

\copy (Select * From foo) To '/tmp/test.csv' With CSV

;메타 명령은 SQL 명령과 달리 줄 바꿈으로 종료되므로 종료는 없습니다 .

에서 워드 프로세서 :

COPY를 psql 명령 \ copy와 혼동하지 마십시오. \ copy는 CODY FROM STDIN 또는 COPY TO STDOUT을 호출 한 다음 psql 클라이언트가 액세스 할 수있는 파일로 데이터를 페치 / 저장합니다. 따라서 파일 접근성과 접근 권한은 \ copy가 사용될 때 서버가 아닌 클라이언트에 의존합니다.

응용 프로그램 프로그래밍 언어 데이터 푸시 또는 페치에 대한 지원도 제공 할 수 있지만 입 / 출력 스트림을 연결하는 방법이 없기 때문에 일반적으로 표준 SQL 문 내에서 COPY FROM STDIN/를 사용할 수 없습니다 TO STDOUT. PHP의 PostgreSQL의 처리기 ( 되지 PDO)은 매우 기본적인 포함 pg_copy_from하고 pg_copy_to대용량 데이터 세트에 대한 효율적인하지 않을 수 PHP 배열로부터 / 복사 기능한다.


131
분명히 위의 예에서는 때때로 사용자가 수퍼 유저 여야합니다. 일반 사용자를위한 버전입니다.) echo“CSP HEADER를 사용하여 COPY (SELECT * from foo) TO STDOUT”| psql -o '/tmp/test.csv'database_name
Drachenfels

10
@ Drachenfels : \copy작동합니다-경로는 클라이언트와 관련이 있으며 세미콜론이 필요하지 않습니다. 내 편집을 참조하십시오.
krlmlr

3
@IMSoP : SQL (postgres 9.3) 함수에 COPY 문을 어떻게 추가 하시겠습니까? 그러면 쿼리가 .csv 파일에 저장됩니까?
jO.

12
\copy하나의 라이너가 필요한 것 같습니다 . 따라서 원하는 방식으로 SQL 형식을 지정하고 복사 / 기능을 배치하는 것의 아름다움을 얻지 못합니다.
isaaclw

1
@AndreSilva 답변에서 알 수 있듯이 명령 줄 클라이언트\copy 의 특수 메타 명령 입니다psql . pgAdmin과 같은 다른 클라이언트에서는 작동하지 않습니다. 이 작업을 수행하기 위해 그래픽 마법사와 같은 자체 도구가있을 수 있습니다.
IMSoP

519

몇 가지 해결책이 있습니다.

1 psql명령

psql -d dbname -t -A -F"," -c "select * from users" > output.csv

이것은 당신처럼, SSH를 통해 그것을 사용 할 수 있다는 큰 장점이있다 ssh postgres@host command취득 할 수 있도록을 -

2 postgres copy명령

COPY (SELECT * from users) To '/tmp/output.csv' With CSV;

3 psql 인터랙티브

>psql dbname
psql>\f ','
psql>\a
psql>\o '/tmp/output.csv'
psql>SELECT * from users;
psql>\q

모두 스크립트에서 사용할 수 있지만 # 1을 선호합니다.

4 pgadmin이지만 스크립팅 할 수 없습니다.


32
IMHO 첫 번째 옵션은 내 보낸 데이터에서 쉼표를 올바르게 이스케이프하지 않기 때문에 오류가 발생하기 쉽습니다.
Piohen

4
또한 psql은 셀 값을 인용하지 않으므로 모든 데이터가 구분 기호를 사용하면 파일이 손상됩니다.
Cerin

7
@Cerin -t는 --tuples-only의 동의어입니다 (열 이름 및 결과 행 수 바닥 글 등의 인쇄 기능 끄기)-열 머리글을 얻기 위해 생략합니다
ic3b3rg

21
그냥 쉼표로 탈출 주장 - 그것은 사실, 방법 # 1이하는 테스트를 하지 값에서 쉼표를 이스케이프 처리 .
MrColes

1
또한 "\ pset footer"를 사용하여 파일에서 행 개수가 증가하지 않도록하십시오
techbrownbags

94

터미널에서 (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

4
콘솔을 다시 인쇄하려면 \ o
metdos

2
CSV 파일을 생성하지 않고 명령 출력을 텍스트 파일에 기록합니다 (쉼표로 구분하지 않음).
루슬란 Kabalin

@RuslanKabalin 예 I 그냥 notticed 콤마로 분리 출력 (CVS)을 작성 지시 한 ammended
마르신 Wasiluk

5
"csv"출력이 제대로 이스케이프되지 않고 SQL 명령이 실행될 때마다 결과가 출력 파일에 연결된다는 점을 지적하여이 답변을 개선했습니다.
Danny Armstrong

필드 값의 줄 바꿈은 어떻습니까? COPY또는 \copy(표준 CSV 형식으로 변환)이 올바르게 핸들에 접근; 이거요?
와일드 카드

37

헤더와 함께 특정 테이블의 모든 열에 관심이 있다면

COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;

이보다 조금 더 간단합니다

COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;

내가 아는 한, 그것은 동등합니다.


1
쿼리가 사용자 정의 인 경우 (IE는 열 별명을 갖거나 다른 테이블을 조인하는 경우) 헤더는 화면에 표시되는 것처럼 열 별명을 인쇄합니다.
Devy

33

CSV 수출 통일

이 정보는 실제로 잘 표현되지 않았습니다. 이것이 내가 이것을 이끌어 내야 할 두 번째이기 때문에, 나는 아무것도 없다면 나 자신을 상기시키기 위해 여기에 넣을 것입니다.

이 작업을 수행하는 가장 좋은 방법은 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 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 터널과 같은 원격 시스템에 TCP / IP 터널과 같은 것을 구성하는 것이 더 복잡하지만, 다른 출력 형식 (2 진)의 경우 /copy로컬 연결을 실행하여 터널링 된 연결 보다 낫습니다 psql. 비슷한 맥락에서, 대량 수입의 경우 소스 파일을 서버로 옮기고 사용하는 COPY것이 아마도 가장 높은 성능 옵션 일 것입니다.

PSQL 파라미터

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를 가져오고 싶습니다.


1
결과는 어디에 저장됩니까? 쿼리가 실행되지만 파일이 컴퓨터의 어느 곳에도 나타나지 않습니다. 이것이 내가하고있는 일 : COPY (c에서 d, '1'에서 a, b 선택) CSVHEADER로 STADOUT하려면> abcd.csv
kRazzy R

1
@kRazzyR 출력은 psql 명령의 stdout으로갑니다. 따라서 궁극적으로 stdout으로하는 것은 데이터가가는 곳입니다. 내 예제에서는 '> file.csv'를 사용하여 파일로 리디렉션합니다. psql -c 매개 변수를 통해 서버로 전송되는 명령 외부에 있는지 확인하려고합니다. '로컬 머신'예제를 참조하십시오.
joshperry

완전한 설명을 주셔서 감사합니다. copy 명령은 psql과 함께 복잡하지 않습니다. 나는 보통 무료 데이터베이스 클라이언트 (dbeaver community edition)를 사용하여 데이터 파일을 가져오고 내 보냅니다. 멋진 매핑 및 서식 도구를 제공합니다. 귀하의 답변은 원격 시스템에서 복사하기위한 훌륭한 예를 제공합니다.
Rich Lysakowski PhD

24

오류 메시지가 나타 났으므로 \ 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;

그리고 그것은 작동하고 있습니다


17

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여기에 사용 된 옵션에 대한 도움말을 참조 하십시오.


12
이것은 실제 CSV 파일이 아니므로 데이터에 쉼표가 있으면 타는 것을 감시하십시오. 따라서 기본 제공되는 COPY 지원을 사용하는 것이 좋습니다. 그러나이 일반적인 기술은 Postgres에서 CSV 이외의 다른 구분 형식으로 내보내기위한 빠른 해킹으로 유용합니다.
Greg Smith

16

COPY TO기능을 지원하지 않는 AWS Redshift에서 작업하고 있습니다.

내 BI 도구는 탭으로 구분 된 CSV를 지원하므로 다음을 사용했습니다.

 psql -h dblocation -p port -U user -d dbname -F $'\t' --no-align -c "SELECT * FROM TABLE" > outfile.csv

16

새로운 버전-psql 12가 지원 --csv됩니다.

psql-개발

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

11

pgAdmin III에는 쿼리 창에서 파일로 내보내는 옵션이 있습니다. 기본 메뉴에는 쿼리-> 파일로 실행 또는 동일한 작업을 수행하는 버튼이 있습니다 (쿼리를 실행하는 일반 녹색 삼각형이 아닌 파란색 플로피 디스크가있는 녹색 삼각형입니다). 쿼리 창에서 쿼리를 실행하지 않으면 IMSoP가 제안한 것을 수행하고 copy 명령을 사용합니다.


최고 관리자가되어야하므로 IMSoP의 답변이 효과가 없었습니다. 이것은 치료를했습니다. 감사!
Mike

9

나는 여러 가지를 시도했지만 그중 일부는 헤더 세부 정보가있는 원하는 CSV를 제공 할 수 없었습니다.

여기 나를 위해 일한 것이 있습니다.

psql -d dbame -U username \
  -c "COPY ( SELECT * FROM TABLE ) TO STDOUT WITH CSV HEADER " > \
  OUTPUT_CSV_FILE.csv

9

패턴 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

2
잘 작동합니다. 감사합니다.
AlexM

6

더 긴 쿼리가 있고 psql을 사용하려면 쿼리를 파일에 넣고 다음 명령을 사용하십시오.

psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv

FWIW, MS Excel에서 올바르게 열리는 CSV 파일을 생성하는 -F","대신 사용해야 했습니다-F";"
CFL_Jeff

4

열 이름이 HEADER 인 CSV 파일을 다운로드하려면 다음 명령을 사용하십시오.

Copy (Select * From tableName) To '/tmp/fileName.csv' With CSV HEADER;

1

JetBrains의 데이터베이스 IDE 인 DataGrip을 적극 권장 합니다. SQL 쿼리를 CSV 파일로 내보낼 수 있습니다 하고 쉽게 SSH 터널링을 설정할 수 있습니다. 설명서에서 "결과 세트"를 언급 할 경우 콘솔의 SQL 쿼리에서 반환 된 결과를 의미합니다.

나는 DataGrip과 관련이 없으며 단지 제품을 좋아합니다!


downvote는 컨텍스트 / 설명이 부족하여 추측 한 것이므로 DataGrip 설명서에 연결했습니다. 공감 비가 다른 이유가 있으면 알려주세요. 위의 CLI 솔루션을 사용했으며 작은 쿼리에서는 DataGrip이 훨씬 쉽습니다.
skeller88

DataGrip의 문제점은 지갑을 손에 넣는다는 것입니다. 무료가 아닙니다. dbeaver.io에서 DBeaver 커뮤니티 에디션을 사용해보십시오 . MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto 등 모든 인기있는 데이터베이스를 지원하는 SQL 프로그래머, DBA 및 분석가를위한 FOSS 다중 플랫폼 데이터베이스 도구입니다.
Rich Lysakowski PhD

쿨 확인하겠습니다. 댓글로 답변을 다시 게시하는 것은 어떻습니까?
skeller88

0

웹 브라우저의 데이터베이스 클라이언트 인 JackDB 는 이것을 매우 쉽게 만듭니다. 특히 Heroku를 사용하는 경우.

원격 데이터베이스에 연결하여 SQL 쿼리를 실행할 수 있습니다.

                                                                                                                                                       소스 (source : jackdb.com )jackdb-heroku


DB가 연결되면 쿼리를 실행하고 CSV 또는 TXT로 내보낼 수 있습니다 (오른쪽 아래 참조).


jackdb 내보내기

참고 : 나는 결코 JackDB와 제휴하지 않습니다. 저는 현재 무료 서비스를 사용하고 있으며 훌륭한 제품이라고 생각합니다.


0

@ skeller88의 요청에 따라 모든 답변을 읽지 않는 사람들이 내 의견을 잃지 않도록 답변으로 내 의견을 다시 게시하고 있습니다 ...

DataGrip의 문제점은 지갑을 손에 넣는다는 것입니다. 무료가 아닙니다. dbeaver.io에서 DBeaver 커뮤니티 에디션을 사용해보십시오. MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto 등 모든 인기있는 데이터베이스를 지원하는 SQL 프로그래머, DBA 및 분석가를위한 FOSS 다중 플랫폼 데이터베이스 도구입니다.

DBeaver Community Edition은 데이터베이스에 연결하고 쿼리를 발행하여 데이터를 검색 한 다음 결과 세트를 다운로드하여 CSV, JSON, SQL 또는 기타 공통 데이터 형식으로 저장하도록합니다. Postgres 용 TOAD, SQL Server 용 TOAD 또는 Toad for Oracle의 실행 가능한 FOSS 경쟁 업체입니다.

DBeaver와 제휴 관계가 없습니다. 가격과 기능을 좋아하지만 DBeaver / Eclipse 애플리케이션을 더 많이 열고 사용자가 연간 구독료를 지불하여 그래프 및 차트를 직접 작성하지 않고 DBeaver / Eclipse에 분석 위젯을 쉽게 추가 할 수 있기를 바랍니다. 응용 프로그램. 내 Java 코딩 기술은 녹슬고 DBeaver가 타사 위젯을 DBeaver Community Edition에 추가하는 기능을 사용하지 못하도록 Eclipse 위젯 빌드 방법을 다시 배우는 데 몇 주가 걸리지 않습니다.

DBeaver 사용자는 Community Edition of DBeaver에 추가 할 분석 위젯을 작성하는 단계에 대한 통찰력이 있습니까?


-3
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'

3
답변을 수정 한 내용을 설명하고 코드 만 답변을 피하십시오
GGO

3
이 코드 스 니펫에 대해 약간의 단기적인 도움을 제공 할 수 있습니다. 적절한 설명 이것이 문제에 대한 좋은 해결책 인지 보여줌으로써 장기적인 가치를 크게 향상시킬 것이며, 다른 비슷한 질문을 가진 미래 독자들에게 더 유용 할 것입니다. 제발 편집 당신이 만든 가정 등 일부 설명을 추가 할 답변을.
Toby Speight

2
이것은 csv 파일이 아닌 json 파일을 생성합니다.
nvoigt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.