psql \copy와 COPY가 파일을 다르게 읽는 이유
조회 1 · 댓글 0
서버에서 COPY table FROM '/path/data.csv'를 돌렸는데 "could not open file"이나 권한 오류가 나면, 파일 경로를 클라이언트 기준으로 착각한 경우가 대부분입니다. 공식 문서에 따르면 COPY가 지정한 파일은 클라이언트가 아니라 서버가 직접 읽고 씁니다. 그래서 파일은 DB 서버 머신에 있어야 하고, 서버 프로세스를 구동하는 OS 유저(보통 postgres) 권한으로 접근 가능해야 합니다. 상대경로는 서버 프로세스의 작업 디렉터리(보통 데이터 디렉터리) 기준으로 해석되니 절대경로 권장입니다. 게다가 파일이나 프로그램을 지정하는 COPY는 superuser이거나 pg_read_server_files 같은 롤을 부여받은 유저만 쓸 수 있습니다.
내 노트북이나 EC2 클라이언트에 있는 파일을 넣고 싶으면 psql 메타명령 \copy를 씁니다. 이건 내부적으로 COPY FROM STDIN / COPY TO STDOUT을 실행하고 파일 입출력은 psql이 대신 처리해서, 파일 접근 권한이 서버가 아니라 로컬 유저 기준이 됩니다. superuser 권한도 필요 없습니다.
# 서버 측 COPY (파일이 DB 서버에 있어야 함, 권한 필요)
COPY members FROM '/var/lib/pgsql/data/members.csv' WITH (FORMAT csv, HEADER);
# 클라이언트 측 \copy (내 로컬 파일, psql 프롬프트에서)
\copy members FROM './members.csv' WITH (FORMAT csv, HEADER)주의할 점 하나. \copy는 모든 데이터가 클라이언트-서버 커넥션을 통과하기 때문에 서버 측 COPY보다 느립니다. 대용량이면 파일을 서버로 옮겨 COPY를 쓰는 편이 낫습니다.
로그인 후 답글을 남길 수 있습니다.