명령어/DB

[PostgreSQL] \copy 쿼리 결과를 CSV로 내보내고 읽어들인다

jykim23 2026. 8. 1. 19:45
반응형

설치·접속: PostgreSQL 설치와 접속

부제: 클라이언트 쪽 파일과 테이블 사이를 CSV로 오가는 psql 전용 명령

# 내보내기: 쿼리 결과를 로컬 CSV 파일로
psql -d shop -c "\copy (SELECT id, name, email FROM users ORDER BY id LIMIT 5) TO 'users.csv' WITH CSV HEADER"
# 읽어들이기: CSV를 테이블로
psql -d shop -c "\copy t_imp FROM 'users.csv' WITH CSV HEADER"
COPY 5
--- users.csv 내용 ---
id,name,email
1,user1,u1@ex.com
2,user2,u2@ex.com
3,user3,u3@ex.com
4,user4,u4@ex.com
5,user5,u5@ex.com

\copy는 psql 메타명령으로, 테이블과 CSV 파일을 양방향으로 옮긴다. SQL의 COPY와 헷갈리기 쉬운데, COPY는 서버 프로세스가 서버 디스크에 파일을 읽고 쓰기 때문에 슈퍼유저 권한과 서버 경로가 필요하다. 반면 \copy는 psql이 실행되는 클라이언트 쪽에서 파일을 다루므로, 일반 유저가 자기 로컬 파일로 손쉽게 덤프하거나 적재할 수 있다. 원격 DB에서 내 노트북으로 데이터를 뽑아올 때 특히 유용하다. WITH CSV HEADER를 붙이면 첫 줄을 컬럼명으로 처리한다.

이렇게도 쓴다

특정 조건의 행만 골라 내보낸다. (조합: WHERE 절)

psql -d shop -c "\copy (SELECT * FROM orders WHERE qty >= 5) TO 'big_orders.csv' WITH CSV HEADER"

 

구분자를 탭으로 바꿔 TSV로 뽑는다.

psql -d shop -c "\copy users TO 'users.tsv' WITH (FORMAT csv, DELIMITER E'\t')"

 

CSV를 임시 테이블에 적재해 검증한다. (조합: TEMP 테이블)

psql -d shop -c 'CREATE TEMP TABLE t_imp(id int, name text, email text);' -c "\copy t_imp FROM 'users.csv' WITH CSV HEADER" -c 'SELECT count(*) FROM t_imp;'

 

표준출력으로 뽑아 셸 파이프에 바로 넘긴다. (조합: STDOUT)

psql -d shop -c "\copy (SELECT name FROM users) TO STDOUT" | sort | uniq -c

 

압축까지 한 번에 걸어 저장 용량을 줄인다. (조합: gzip)

psql -d shop -c "\copy orders TO STDOUT WITH CSV HEADER" | gzip > orders.csv.gz
반응형