COPY INTO <location>
COPY INTO
테이블(또는 쿼리)의 데이터를 다음 위치 중 하나의 하나 이상의 파일로 언로드(unload)하는 명령이에요:
- 이름 있는 내부 스테이지(또는 테이블/사용자 스테이지). 이 파일들은 GET 명령을 사용해 스테이지/위치에서 다운로드할 수 있어요.
- 외부 위치(Amazon S3, Google Cloud Storage 또는 Microsoft Azure)를 참조하는 이름 있는 외부 스테이지.
- 외부 위치(Amazon S3, Google Cloud Storage 또는 Microsoft Azure).
출처: 문서
본문
관련 명령: COPY INTO
| 지원 값 | 참고 |
|---|---|
| AUTO | 언로드된 파일은 기본값인 gzip으로 자동 압축돼요. |
| GZIP | |
| BZ2 | |
| BROTLI | Brotli 압축 파일을 로드할 때 반드시 지정해야 해요. |
| ZSTD | Zstandard v0.8(이상) 지원. |
| DEFLATE | 언로드된 파일은 Deflate(zlib 헤더 포함, RFC1950)로 압축돼요. |
| RAW_DEFLATE | 언로드된 파일은 Raw Deflate(헤더 없음, RFC1951)로 압축돼요. |
| NONE | 언로드된 파일이 압축되지 않아요. |
기본값: AUTO
RECORD_DELIMITER = 'string' | NONE
언로드된 파일에서 레코드를 구분하는 하나 이상의 싱글바이트 또는 멀티바이트 문자예요. 일반적인 이스케이프 시퀀스 또는 싱글바이트/멀티바이트 문자를 허용해요. 싱글바이트 문자는 8진수 값(\\ 접두사) 또는 16진수 값(0x 또는 \\x 접두사)을 사용해요. 예를 들어 캐럿 악센트(^) 문자로 구분되는 레코드는 8진수(\\136) 또는 16진수(0x5e) 값을 지정해요. 멀티바이트 문자는 16진수 값(\\x 접두사)을 사용해요. RECORD_DELIMITER 또는 FIELD_DELIMITER의 구분자는 다른 파일 형식 옵션의 구분자 하위 문자열일 수 없어요. 지정된 구분자는 유효한 UTF-8 문자여야 하고 임의의 바이트 시퀀스가 아니어야 해요. 구분자는 최대 20자로 제한돼요. 또한 NONE 값을 허용해요.
기본값: 새 줄 문자. "새 줄"은 논리적이어서 Windows 플랫폼의 파일에서는 \r\n이 새 줄로 이해돼요.
FIELD_DELIMITER = 'string' | NONE
언로드된 파일에서 필드를 구분하는 하나 이상의 싱글바이트 또는 멀티바이트 문자예요. RECORD_DELIMITER와 같은 규칙이 적용돼요. 기본값: 쉼표(,).
FILE_EXTENSION = 'string'
스테이지에 언로드된 파일의 확장자를 지정하는 문자열이에요. 모든 확장자를 허용해요. 원하는 소프트웨어나 서비스가 읽을 수 있는 유효한 파일 확장자를 지정하는 것은 사용자의 책임이에요. SINGLE copy 옵션이 TRUE이면 COPY 명령은 기본적으로 확장자 없는 파일을 언로드해요. 파일 확장자를 지정하려면 internal_location 또는 external_location 경로에 파일 이름과 확장자를 제공해요. 예: copy into @stage/data.csv ....
기본값: null. 즉 파일 확장자는 형식 유형에 의해 결정돼요 (예: COMPRESSION이 설정된 경우 .csv[compression]).
DATE_FORMAT = 'string' | AUTO
언로드된 데이터 파일의 날짜 값 형식을 정의하는 문자열이에요. 값이 지정되지 않거나 AUTO로 설정되면 DATE_OUTPUT_FORMAT 파라미터 값이 사용돼요. 기본값: AUTO.
TIME_FORMAT = 'string' | AUTO
언로드된 데이터 파일의 시간 값 형식을 정의하는 문자열이에요. 값이 지정되지 않거나 AUTO로 설정되면 TIME_OUTPUT_FORMAT 파라미터 값이 사용돼요. 기본값: AUTO.
TIMESTAMP_FORMAT = 'string' | AUTO
언로드된 데이터 파일의 타임스탬프 값 형식을 정의하는 문자열이에요. 값이 지정되지 않거나 AUTO로 설정되면 TIMESTAMP_OUTPUT_FORMAT 파라미터 값이 사용돼요. 기본값: AUTO.
BINARY_FORMAT = HEX | BASE64 | UTF8
바이너리 출력의 인코딩 형식을 정의하는 문자열(상수)이에요. 이 옵션은 테이블의 바이너리 열에서 데이터를 언로드할 때 사용할 수 있어요. 기본값: HEX.
ESCAPE = 'character' | NONE
감싸졌거나 감싸지지 않은 필드 값에 대한 이스케이프 문자로 사용되는 싱글바이트 문자 문자열이에요. 이스케이프 문자는 문자 시퀀스의 후속 문자에 대한 대체 해석을 호출해요. 데이터에서 FIELD_OPTIONALLY_ENCLOSED_BY 문자의 인스턴스를 리터럴로 해석하는 데 사용할 수 있어요. 일반적인 이스케이프 시퀀스, 8진수 값, 16진수 값을 허용해요. FIELD_OPTIONALLY_ENCLOSED_BY를 설정해 필드를 감싸는 문자를 지정해요. 이 옵션이 설정되면 ESCAPE_UNENCLOSED_FIELD에 설정된 이스케이프 문자를 재정의해요. 기본값: NONE.
ESCAPE_UNENCLOSED_FIELD = 'character' | NONE
감싸지지 않은 필드 값에만 사용되는 이스케이프 문자인 싱글바이트 문자 문자열이에요. 데이터에서 FIELD_DELIMITER 또는 RECORD_DELIMITER 문자의 인스턴스를 리터럴로 해석하는 데 사용할 수 있어요. ESCAPE가 설정되면 해당 파일 형식 옵션에 설정된 이스케이프 문자가 이 옵션을 재정의해요. 기본값: 백슬래시(\).
FIELD_OPTIONALLY_ENCLOSED_BY = 'character' | NONE
문자열을 감싸는 데 사용되는 문자예요. 값은 NONE, 작은따옴표 문자(') 또는 큰따옴표 문자(")일 수 있어요. 소스 테이블의 필드에 이 문자가 포함되면 Snowflake는 언로드 시 같은 문자로 이스케이프해요. 예를 들어 값이 큰따옴표 문자이고 필드에 A "B" C라는 문자열이 포함되면 Snowflake는 A ""B"" C처럼 큰따옴표를 이스케이프해요. 기본값: NONE.
NULL_IF = ( 'string1' [ , 'string2' ... ] ) | ()
SQL NULL에서 변환하는 데 사용되는 문자열이에요. Snowflake는 SQL NULL 값을 목록의 첫 번째 값으로 변환해요. NULL_IF = ()를 지정하면 Snowflake는 NULL 값을 빈 필드(,,)로 변환해요. 기본값: \N.
EMPTY_FIELD_AS_NULL = TRUE | FALSE
FIELD_OPTIONALLY_ENCLOSED_BY와 함께 사용돼요. FIELD_OPTIONALLY_ENCLOSED_BY = NONE일 때 EMPTY_FIELD_AS_NULL = FALSE로 설정하면 테이블의 빈 문자열을 필드 값을 감싸는 따옴표 없이 빈 문자열 값으로 언로드하도록 지정해요. TRUE로 설정하면 FIELD_OPTIONALLY_ENCLOSED_BY가 문자열을 감싸는 문자를 지정해야 해요. 기본값: TRUE.
TYPE = JSON
COMPRESSION = AUTO | GZIP | BZ2 | BROTLI | ZSTD | DEFLATE | RAW_DEFLATE | NONE
지정된 압축 알고리즘으로 데이터 파일을 압축해요. 기본값: AUTO.
FILE_EXTENSION = 'string' | NONE
스테이지에 언로드된 파일의 확장자를 지정하는 문자열이에요. 기본값: null.
TYPE = PARQUET
COMPRESSION = AUTO | LZO | SNAPPY | NONE 지정된 압축 알고리즘으로 데이터 파일을 압축해요.
| 지원 값 | 참고 |
|---|---|
| AUTO | 파일은 기본 압축 알고리즘인 Snappy로 압축돼요. |
| LZO | 기본적으로 파일은 Snappy 알고리즘으로 압축돼요. 대신 LZO 압축을 적용하려면 이 값을 지정해요. |
| SNAPPY | 기본적으로 파일은 Snappy 알고리즘으로 압축돼요. 선택적으로 이 값을 지정할 수 있어요. |
| NONE | 언로드된 파일이 압축되지 않도록 지정해요. |
기본값: AUTO
SNAPPY_COMPRESSION = TRUE | FALSE
언로드된 파일이 SNAPPY 알고리즘으로 압축되는지 지정하는 부울이에요. 더 이상 사용되지 않아요. COMPRESSION = SNAPPY를 대신 사용하세요. 기본값: TRUE.
Copy 옵션 (copyOptions)
하나 이상의 copy 옵션을 지정할 수 있어요.
OVERWRITE = TRUE | FALSE
COPY 명령이 파일이 저장되는 위치에서 일치하는 이름의 기존 파일이 있으면 덮어쓸지 지정하는 부울이에요. 이 옵션은 COPY 명령이 언로드하는 파일의 이름과 일치하지 않는 기존 파일은 제거하지 않아요.
많은 경우 이 옵션을 활성화하면 같은 COPY INTO data_0_1_0). 병렬 실행 스레드 수는 언로드 작업마다 다를 수 있어요. 언로드 작업이 쓴 파일 이름이 이전 작업이 쓴 파일 이름과 같지 않으면 이 copy 옵션을 포함한 SQL 문은 기존 파일을 교체할 수 없어 중복 파일이 발생해요.
또한 드물게 머신 또는 네트워크 오류가 발생하면 언로드 작업이 재시도돼요. 이 시나리오에서 언로드 작업은 첫 번째 시도에서 이전에 쓴 파일을 먼저 제거하지 않고 스테이지에 추가 파일을 써요.
대상 스테이지의 데이터 중복을 피하려면 OVERWRITE = TRUE 대신 INCLUDE_QUERY_ID = TRUE copy 옵션을 설정하고, 각 언로드 작업 사이에 대상 스테이지와 경로의 모든 데이터 파일을 제거하는 것이 좋아요.
기본값: FALSE
SINGLE = TRUE | FALSE
단일 파일 또는 여러 파일을 생성할지 지정하는 부울이에요. FALSE이면 *path*에 파일 이름 접두사가 포함되어야 해요.
SINGLE = TRUE이면 COPY는 FILE_EXTENSION 파일 형식 옵션을 무시하고 단순히 data라는 이름의 파일을 출력해요. 파일 확장자를 지정하려면 내부 또는 외부 위치 *path*에 파일 이름과 확장자를 제공해요. 예: COPY INTO @mystage/data.csv .... 또한 COMPRESSION 파일 형식 옵션도 지원되는 압축 알고리즘(예: GZIP) 중 하나로 명시적으로 설정되면 지정된 내부 또는 외부 위치 *path*는 해당 파일 확장자(예: gz)가 있는 파일 이름으로 끝나야 파일을 적절한 도구로 압축 해제할 수 있어요. 예: COPY INTO @mystage/data.gz ... 또는 COPY INTO @mystage/data.csv.gz ....
기본값: FALSE
MAX_FILE_SIZE = *num*
스레드당 병렬로 생성할 각 파일의 최대 크기(바이트)를 지정해요. Snowflake는 성능 최적화를 위해 병렬 실행을 활용해요. 스레드 수는 수정할 수 없어요. 실제 언로드된 파일 크기와 언로드된 파일 수는 총 데이터 양과 병렬 처리를 위해 사용 가능한 노드 수에 따라 달라져요. 언로드된 파일 크기는 웨어하우스 워커의 사용 가능한 메모리에 따라 달라지며, 이는 웨어하우스 크기와 사용 가능한 리소스, 그리고 웨어하우스에서 실행되는 동시 쿼리 수에 따라 달라져요. MAX_FILE_SIZE는 상한을 설정하지만 파일이 이 크기에 도달함을 보장하지는 않아요. 메모리 제약으로 파일 완성이 더 일찍 필요하면 파일은 지정된 MAX_FILE_SIZE보다 작을 수 있어요.
COPY 명령은 한 번에 한 세트의 테이블 행을 언로드해요. 매우 작은 MAX_FILE_SIZE 값(예: 1MB 미만)을 설정하면 행 세트의 데이터 양이 지정된 크기를 초과할 수 있어요.
기본값: 16777216 (16MB), 최대: 5368709120 (5GB).
INCLUDE_QUERY_ID = TRUE | FALSE
언로드된 데이터 파일의 파일 이름에 UUID(범용 고유 식별자)를 포함해 언로드된 파일을 고유하게 식별할지 지정하는 부울이에요. 이 옵션은 동시 COPY 문이 언로드된 파일을 실수로 덮어쓰지 않도록 보장하는 데 도움이 돼요.
TRUE이면 언로드된 파일 이름에 UUID가 추가돼요. UUID는 데이터 파일을 언로드하는 데 사용된 COPY 문의 쿼리 ID예요. UUID는 파일 이름의 세그먼트예요: <path>/data_<uuid>_<name>.<extension>. 이 옵션은 내부 재시도가 발생하면 중복 데이터를 언로드하지 못하게도 해요. 내부 재시도가 발생하면 Snowflake는 부분 언로드 파일 세트(UUID로 식별)를 삭제한 다음 copy 작업을 다시 시작해요. FALSE이면 언로드된 데이터 파일에 UUID가 추가되지 않아요.
INCLUDE_QUERY_ID = TRUE는 언로드된 테이블 행을 별도 파일로 분할할 때(PARTITION BY *expr*설정) 기본 copy 옵션 값이에요. 이 값을 FALSE로 변경할 수 없어요.INCLUDE_QUERY_ID = TRUE는 다음 copy 옵션 중 하나가 설정되면 지원되지 않아요:SINGLE = TRUE,OVERWRITE = TRUE.- 드물게 머신 또는 네트워크 오류가 발생하면 언로드 작업이 재시도돼요. 이 시나리오에서 언로드 작업은 현재 쿼리 ID의 UUID로 스테이지에 쓴 파일을 제거한 다음 데이터를 다시 언로드하려고 해요. 스테이지에 쓰인 새 파일은 재시도된 쿼리 ID를 UUID로 가져요.
기본값: FALSE
DETAILED_OUTPUT = TRUE | FALSE
명령 출력이 언로드 작업 자체를 설명할지, 아니면 작업 결과로 언로드된 개별 파일을 설명할지 지정하는 부울이에요.
TRUE이면 명령 출력에는 지정된 스테이지로 언로드된 각 파일에 대한 행이 포함돼요. 열은 각 파일의 경로와 이름, 크기, 파일에 언로드된 행 수를 보여줘요.FALSE이면 명령 출력은 전체 언로드 작업을 설명하는 단일 행으로 구성돼요. 열은 압축 전후(해당하는 경우)에 테이블에서 언로드된 총 데이터 양과 언로드된 총 행 수를 보여줘요.
기본값: FALSE
사용 참고사항 (Usage notes)
STORAGE_INTEGRATION또는CREDENTIALS는 프라이빗 저장소 위치(Amazon S3, Google Cloud Storage 또는 Microsoft Azure)로 직접 언로드하는 경우에만 적용돼요. 공용 버킷에 언로드하면 안전한 접근이 필요하지 않고, 이름 있는 외부 스테이지에 언로드하면 스테이지가 버킷에 접근하는 데 필요한 모든 자격 증명 정보를 제공해요.- 현재 네임스페이스에서 파일 형식을 참조하면 형식 식별자 주변의 작은따옴표를 생략할 수 있어요.
JSON은 테이블의 VARIANT 열에서 데이터를 언로드할 때만TYPE으로 지정할 수 있어요.CSV,JSON또는PARQUET유형의 파일로 언로드할 때: 기본적으로 VARIANT 열은 출력 파일에서 단순 JSON 문자열로 변환돼요. 데이터를 Parquet LIST 값으로 언로드하려면 (TO_ARRAY 함수를 사용해) 열 값을 배열로 명시적으로 캐스팅해요. VARIANT 열에 XML이 포함되면 TO_XML 함수를 사용해 캐스팅하는 것을 권장해요.PARQUET유형의 파일로 언로드할 때: TIMESTAMP_TZ 또는 TIMESTAMP_LTZ 데이터를 언로드하면 오류가 발생해요. Snowflake가 Parquet 파일을 생성할 때 Apache Arrow 라이브러리 21.1.0을 사용해요. Parquet 소비자가 이 버전과 호환되는지 확인하세요.- 소스 테이블에 0행이 포함되면 COPY 작업은 데이터 파일을 언로드하지 않아요.
- 이 SQL 명령은 비어 있지 않은 저장소 위치에 언로드할 때 경고를 반환하지 않아요. 데이터 파이프라인이 저장소 위치의 파일을 소비하는 경우 예기치 않은 동작을 피하려면 빈 저장소 위치에만 쓰는 것이 좋아요.
- 실패한 언로드 작업: 실패한 언로드 작업도 여전히 언로드된 데이터 파일을 생성할 수 있어요(예: 문이 취소되거나 시간 초과 한도를 초과한 경우). 분할 데이터 언로드 또는
INCLUDE_QUERY_ID = TRUE의 경우 Snowflake는 언로드된 파일을 정리하려고 시도하고 실패한 언로드 작업을 재시도할 수 있어요. 정리 작업이 시간 초과되어 오류 메시지를 반환하면 실패한 쿼리 ID를 사용해 파일을 찾아 수동으로 제거할 수 있어요. - 다른 지역의 클라우드 저장소로의 실패한 언로드 작업은 데이터 전송 비용이 발생해요.
- 열에 마스킹 정책이 설정되면 마스킹 정책이 데이터에 적용되어 권한 없는 사용자는 열에서 마스킹된 데이터를 보게 돼요.
- 이 명령의 실행 상태와 기록을 보려면 QUERY_HISTORY 뷰를 사용하세요.
- 아웃바운드 프라이빗 연결의 경우 외부 위치(외부 저장소 URI)로 직접 언로드하는 것은 지원되지 않아요. 대신 아웃바운드 프라이빗 연결용으로 구성된 스토리지 통합이 있는 외부 스테이지를 사용하세요.
예 (Examples)
테이블에서 테이블 스테이지의 파일로 데이터 언로드
orderstiny 테이블의 데이터를 폴더/파일 이름 접두사(result/data_), 이름 있는 파일 형식(myformat), gzip 압축을 사용해 테이블의 스테이지로 언로드해요:
COPY INTO @%orderstiny/result/data_
FROM orderstiny FILE_FORMAT = (FORMAT_NAME ='myformat' COMPRESSION='GZIP');
쿼리에서 이름 있는 내부 스테이지의 파일로 데이터 언로드
쿼리 결과를 이름 있는 내부 스테이지(my_stage)의 폴더/파일 이름 접두사(result/data_), 이름 있는 파일 형식(myformat), gzip 압축을 사용해 언로드해요:
COPY INTO @my_stage/result/data_ FROM (SELECT * FROM orderstiny)
file_format=(format_name='myformat' compression='gzip');
테이블에서 외부 위치의 파일로 데이터 직접 언로드
이 옵션은 아웃바운드 프라이빗 연결에서 지원되지 않아요. 대신 외부 스테이지를 사용하세요.
Amazon S3:
-- 참조된 스토리지 통합 `myint`를 사용해 S3 버킷에 접근
COPY INTO 's3://mybucket/unload/'
FROM mytable
STORAGE_INTEGRATION = myint
FILE_FORMAT = (FORMAT_NAME = my_csv_format);
-- 제공된 자격 증명을 사용해 S3 버킷에 접근
COPY INTO 's3://mybucket/unload/'
FROM mytable
CREDENTIALS = (AWS_KEY_ID='xxxx' AWS_SECRET_KEY='xxxxx' AWS_TOKEN='xxxxxx')
FILE_FORMAT = (FORMAT_NAME = my_csv_format);
Google Cloud Storage:
COPY INTO 'gcs://mybucket/unload/'
FROM mytable
STORAGE_INTEGRATION = myint
FILE_FORMAT = (FORMAT_NAME = my_csv_format);
Microsoft Azure:
COPY INTO 'azure://myaccount.blob.core.windows.net/unload/'
FROM mytable
STORAGE_INTEGRATION = myint
FILE_FORMAT = (FORMAT_NAME = my_csv_format);
COPY INTO 'azure://myaccount.blob.core.windows.net/mycontainer/unload/'
FROM mytable
CREDENTIALS=(AZURE_SAS_TOKEN='xxxx')
FILE_FORMAT = (FORMAT_NAME = my_csv_format);
언로드된 행을 Parquet 파일로 분할
다음 예는 날짜 열과 시간 열 두 열의 값으로 언로드된 행을 Parquet 파일로 분할하고, 각 언로드 파일의 최대 크기를 지정해요:
CREATE or replace TABLE t1 (
dt date,
ts time
)
AS
SELECT TO_DATE($1)
,TO_TIME($2)
FROM VALUES
('2020-01-28', '18:05')
,('2020-01-28', '22:57')
,('2020-01-28', NULL)
,('2020-01-29', '02:15')
;
-- 날짜와 시간(시간)으로 언로드 데이터를 분할하고, 스레드당 병렬 생성 파일의 상한(32MB)을 설정
COPY INTO @%t1
FROM t1
PARTITION BY ('date=' || to_varchar(dt, 'YYYY-MM-DD') || '/hour=' || to_varchar(date_part(hour, ts))) -- 의미 있는 파일 이름을 출력하도록 라벨과 열 값을 결합
FILE_FORMAT = (TYPE=parquet)
MAX_FILE_SIZE = 32000000
HEADER=true;
LIST @%t1;
언로드된 파일에서 NULL/빈 필드 데이터 유지
-- 테이블 열 값 보기
SELECT * FROM HOME_SALES;
-- 사용자 개인 스테이지로 테이블 데이터 언로드. 파일 형식 옵션이 NULL 값과 빈 값을 모두 출력 파일에 유지
COPY INTO @~ FROM HOME_SALES
FILE_FORMAT = (TYPE = csv NULL_IF = ('NULL', 'null') EMPTY_FIELD_AS_NULL = false);
-- 출력 파일 내용
Lexington,MA,95815,Residential,268880,2017-03-28
Belmont,MA,95815,Residential,,2017-02-21
Winchester,MA,NULL,Residential,,2017-01-31
단일 파일로 데이터 언로드
copy into @~ from HOME_SALES
single = true;
언로드된 파일 이름에 UUID 포함
-- T1 테이블에서 T1 테이블 스테이지로 행 언로드
COPY INTO @%t1
FROM t1
FILE_FORMAT=(TYPE=parquet)
INCLUDE_QUERY_ID=true;
-- COPY INTO 위치 문의 쿼리 ID 검색
SELECT last_query_id();
언로드할 데이터 검증 (쿼리에서)
COPY INTO @my_stage
FROM (SELECT * FROM orderstiny LIMIT 5)
VALIDATION_MODE='RETURN_ROWS';