COPY INTO <location>

COPY INTO

테이블(또는 쿼리)의 데이터를 다음 위치 중 하나의 하나 이상의 파일로 언로드(unload)하는 명령이에요:

  • 이름 있는 내부 스테이지(또는 테이블/사용자 스테이지). 이 파일들은 GET 명령을 사용해 스테이지/위치에서 다운로드할 수 있어요.
  • 외부 위치(Amazon S3, Google Cloud Storage 또는 Microsoft Azure)를 참조하는 이름 있는 외부 스테이지.
  • 외부 위치(Amazon S3, Google Cloud Storage 또는 Microsoft Azure).

출처: 문서

본문

관련 명령: COPY INTO

구문 (Syntax)

COPY INTO { internalStage | externalStage | externalLocation }
     FROM { [<namespace>.]<table_name> | ( <query> ) }
[ PARTITION BY <expr> ]
[ FILE_FORMAT = ( { FORMAT_NAME = '[<namespace>.]<file_format_name>' |
                    TYPE = { CSV | JSON | PARQUET } [ formatTypeOptions ] } ) ]
[ copyOptions ]
[ VALIDATION_MODE = RETURN_ROWS ]
[ HEADER ]

여기서:

internalStage ::=
    @[<namespace>.]<int_stage_name>[/<path>]
  | @[<namespace>.]%<table_name>[/<path>]
  | @~[/<path>]
externalStage ::=
  @[<namespace>.]<ext_stage_name>[/<path>]
externalLocation (for Amazon S3) ::=
  '<protocol>://<bucket>[/<path>]'
  [ { STORAGE_INTEGRATION = <integration_name> } | { CREDENTIALS = ( {  { AWS_KEY_ID = '<string>' AWS_SECRET_KEY = '<string>' [ AWS_TOKEN = '<string>' ] } } ) } ]
  [ ENCRYPTION = ( [ TYPE = 'AWS_CSE' ] [ MASTER_KEY = '<string>' ] |
                   [ TYPE = 'AWS_SSE_S3' ] |
                   [ TYPE = 'AWS_SSE_KMS' [ KMS_KEY_ID = '<string>' ] ] |
                   [ TYPE = 'NONE' ] ) ]
externalLocation (for Google Cloud Storage) ::=
  'gcs://<bucket>[/<path>]'
  [ STORAGE_INTEGRATION = <integration_name> ]
  [ ENCRYPTION = ( [ TYPE = 'GCS_SSE_KMS' ] [ KMS_KEY_ID = '<string>' ] | [ TYPE = 'NONE' ] ) ]
externalLocation (for Microsoft Azure) ::=
  'azure://<account>.blob.core.windows.net/<container>[/<path>]'
  [ { STORAGE_INTEGRATION = <integration_name> } | { CREDENTIALS = ( [ AZURE_SAS_TOKEN = '<string>' ] ) } ]
  [ ENCRYPTION = ( [ TYPE = { 'AZURE_CSE' | 'NONE' } ] [ MASTER_KEY = '<string>' ] ) ]
formatTypeOptions ::=
-- If FILE_FORMAT = ( TYPE = CSV ... )
     COMPRESSION = AUTO | GZIP | BZ2 | BROTLI | ZSTD | DEFLATE | RAW_DEFLATE | NONE
     RECORD_DELIMITER = '<string>' | NONE
     FIELD_DELIMITER = '<string>' | NONE
     FILE_EXTENSION = '<string>'
     ESCAPE = '<character>' | NONE
     ESCAPE_UNENCLOSED_FIELD = '<character>' | NONE
     DATE_FORMAT = '<string>' | AUTO
     TIME_FORMAT = '<string>' | AUTO
     TIMESTAMP_FORMAT = '<string>' | AUTO
     BINARY_FORMAT = HEX | BASE64 | UTF8
     FIELD_OPTIONALLY_ENCLOSED_BY = '<character>' | NONE
     NULL_IF = ( '<string1>' [ , '<string2>' , ... ] )
     EMPTY_FIELD_AS_NULL = TRUE | FALSE
-- If FILE_FORMAT = ( TYPE = JSON ... )
     COMPRESSION = AUTO | GZIP | BZ2 | BROTLI | ZSTD | DEFLATE | RAW_DEFLATE | NONE
     FILE_EXTENSION = '<string>'
-- If FILE_FORMAT = ( TYPE = PARQUET ... )
     COMPRESSION = AUTO | LZO | SNAPPY | NONE
     SNAPPY_COMPRESSION = TRUE | FALSE
copyOptions ::=
     OVERWRITE = TRUE | FALSE
     SINGLE = TRUE | FALSE
     MAX_FILE_SIZE = <num>
     INCLUDE_QUERY_ID = TRUE | FALSE
     DETAILED_OUTPUT = TRUE | FALSE

필수 파라미터

INTO ... 데이터 파일이 언로드되는 내부 또는 외부 위치를 지정해요.

FROM ... 언로드할 데이터의 소스를 지정해요. 테이블이거나 쿼리일 수 있어요.

[*namespace*.]*table_name* 데이터가 언로드되는 테이블의 이름을 지정해요. 네임스페이스는 선택적으로 테이블이 있는 데이터베이스와/또는 스키마를 *database_name*.*schema_name* 또는 *schema_name* 형태로 지정해요. 사용자 세션에서 데이터베이스와 스키마를 현재 사용 중이면 선택 사항이고, 그렇지 않으면 필수예요.

( *query* ) 파일에 언로드할 데이터를 반환하는 SELECT 문이에요. 쿼리에 LIMIT / FETCH 절을 지정해 반환되는 행 수를 제한할 수 있어요.

CAST , :: 함수를 사용해 열 값을 데이터 유형으로 캐스팅할 때, 데이터 유형이 모든 열 값을 지원하는지 확인하세요. 지정된 데이터 유형에 너무 긴 값은 잘릴 수 있어요.

추가 클라우드 공급자 파라미터

STORAGE_INTEGRATION = *integration_name* 또는 CREDENTIALS = ( *cloud_specific_credentials* ) COPY 문이 대상 클라우드 저장소 위치에 대해 외부 스테이지 이름이 아닌 외부 저장소 URI를 지정할 때 지원돼요. 언로드된 파일이 스테이징되는 프라이빗 저장소 컨테이너에 접속하고 접근하기 위한 클라우드 공급자 보안 자격 증명을 지정해요. 외부 프라이빗 클라우드 저장소 위치로 언로드할 때만 필요해요. 공용 버킷/컨테이너에는 필요하지 않아요.

Amazon S3

STORAGE_INTEGRATION = *integration_name* 외부 클라우드 저장소에 대한 인증 책임을 Snowflake IAM(Identity and Access Management) 엔티티에 위임하는 데 사용되는 스토리지 통합(storage integration)의 이름을 지정해요. 자세한 내용은 CREATE STORAGE INTEGRATION을 참고하세요.

Snowflake는 스토리지 통합의 사용을 권장해요. 이 옵션은 스테이지를 만들거나 데이터를 로드할 때 CREDENTIALS 파라미터로 클라우드 저장소 자격 증명을 제공할 필요가 없게 해요.

CREDENTIALS = ( AWS_KEY_ID = '*string*' AWS_SECRET_KEY = '*string*' [ AWS_TOKEN = '*string*' ] ) 또는 CREDENTIALS = ( AWS_ROLE = '*string*' ) AWS에 접속하고 언로드된 파일이 스테이징되는 프라이빗 S3 버킷에 접근하기 위한 보안 자격 증명을 지정해요. 자세한 내용은 Amazon S3에 대한 안전한 접근 구성을 참고하세요.

지정하는 자격 증명은 버킷에 대한 Snowflake 접근 권한을 AWS IAM 사용자와 연결했는지 역할과 연결했는지에 따라 달라요:

  • IAM 사용자: 임시 IAM 자격 증명이 필요해요. 임시(또는 "scoped") 자격 증명은 AWS Security Token Service(STS)가 생성하며 세 가지 구성 요소(AWS_KEY_ID, AWS_SECRET_KEY, AWS_TOKEN)로 구성돼요. 세 가지 모두 프라이빗 버킷에 접근하는 데 필요해요. 지정된 기간이 지나면 임시 자격 증명은 만료되어 더 이상 사용할 수 없어요. 그때 새 유효한 임시 자격 증명 세트를 생성해야 해요.

COPY 명령은 복잡한 구문과 자격 증명 같은 민감한 정보를 포함해요. 또한 자주 실행되고 스크립트나 워크시트에 저장되는 경우가 많아 민감한 정보가 우발적으로 노출될 수 있어요. COPY 명령은 영구(또는 "장기") 자격 증명 사용을 허용하지만, 보안상의 이유로 COPY 명령에서 영구 자격 증명을 사용하지 마세요. 대신 임시 자격 증명을 사용하세요. 영구 자격 증명을 사용해야 한다면 자격 증명을 한 번 입력하고 안전하게 저장하는 외부 스테이지를 사용하세요.

  • IAM 역할: 보안 자격 증명과 접근 키를 생략하고 대신 AWS_ROLE로 역할을 식별하고 AWS 역할 ARN(Amazon Resource Name)을 지정해요.

AWS IAM 역할을 사용해 프라이빗 S3 버킷에 접근해 데이터를 로드하거나 언로드하는 기능은 이제 더 이상 사용되지 않아요(즉, 향후 릴리스에서 지원이 제거될 예정). 기존 S3 스테이지가 이 기능을 사용한다면 스토리지 통합 객체를 참조하도록 수정하는 것이 좋아요.

Google Cloud Storage

STORAGE_INTEGRATION = *integration_name* 외부 클라우드 저장소에 대한 인증 책임을 Snowflake IAM 엔티티에 위임하는 데 사용되는 스토리지 통합의 이름을 지정해요. 자세한 내용은 CREATE STORAGE INTEGRATION을 참고하세요.

Microsoft Azure

STORAGE_INTEGRATION = *integration_name* 외부 클라우드 저장소에 대한 인증 책임을 Snowflake IAM 엔티티에 위임하는 데 사용되는 스토리지 통합의 이름을 지정해요. 자세한 내용은 CREATE STORAGE INTEGRATION을 참고하세요.

Snowflake는 스토리지 통합의 사용을 권장해요. 이 옵션은 스테이지를 만들거나 데이터를 로드할 때 CREDENTIALS 파라미터로 클라우드 저장소 자격 증명을 제공할 필요가 없게 해요.

CREDENTIALS = ( AZURE_SAS_TOKEN = '*string*' ) Azure에 접속하고 데이터가 들어 있는 파일이 스테이징되는 프라이빗 컨테이너에 접근하기 위한 SAS(공유 액세스 서명) 토큰을 지정해요. 자격 증명은 Azure가 생성해요.

ENCRYPTION = ( *cloud_specific_encryption* ) 임시 COPY 문(이름 있는 외부 스테이지를 참조하지 않는 문)에서 사용돼요. 암호화된 저장소 위치의 파일로 데이터를 언로드할 때만 필요해요.

Amazon S3 ENCRYPTION = ( [ TYPE = 'AWS_CSE' ] [ MASTER_KEY = '<string>' ] | [ TYPE = 'AWS_SSE_S3' ] | [ TYPE = 'AWS_SSE_KMS' [ KMS_KEY_ID = '<string>' ] ] | [ TYPE = 'NONE' ] )

TYPE = ... 사용되는 암호화 유형을 지정해요. 가능한 값은 다음과 같아요:

  • AWS_CSE: 클라이언트 측 암호화(MASTER_KEY 값 필요). 현재 제공하는 클라이언트 측 마스터 키는 대칭 키만 가능해요. MASTER_KEY 값을 제공하면 Snowflake는 TYPE = AWS_CSE로 가정해요.
  • AWS_SSE_S3: 추가 암호화 설정이 필요 없는 서버 측 암호화.
  • AWS_SSE_KMS: 선택적 KMS_KEY_ID 값을 받는 서버 측 암호화.
  • NONE: 암호화 없음.

MASTER_KEY = '*string*' (AWS_CSE 암호화에만 적용) 버킷의 파일을 암호화하는 데 사용되는 클라이언트 측 마스터 키를 지정해요. 마스터 키는 Base64로 인코딩된 128비트 또는 256비트 키여야 해요.

KMS_KEY_ID = '*string*' (AWS_SSE_KMS 암호화에만 적용) 버킷에 언로드된 파일을 암호화하는 데 사용되는 AWS KMS 관리 키의 ID를 선택적으로 지정해요. 값이 제공되지 않으면 기본 KMS 키 ID가 언로드 시 파일을 암호화하는 데 사용돼요.

Google Cloud Storage ENCRYPTION = ( [ TYPE = 'GCS_SSE_KMS' | 'NONE' ] [ KMS_KEY_ID = '*string*' ] )

TYPE = ... 사용되는 암호화 유형을 지정해요.

  • GCS_SSE_KMS: 선택적 KMS_KEY_ID 값을 받는 서버 측 암호화.
  • NONE: 암호화 없음.

KMS_KEY_ID = '*string*' (GCS_SSE_KMS 암호화에만 적용) 버킷에 언로드된 파일을 암호화하는 데 사용되는 Cloud KMS 관리 키의 ID를 선택적으로 지정해요. 값이 제공되지 않으면 버킷에 설정된 기본 KMS 키 ID가 언로드 시 파일을 암호화하는 데 사용돼요.

Microsoft Azure ENCRYPTION = ( [ TYPE = 'AZURE_CSE' | 'NONE' ] [ MASTER_KEY = '*string*' ] )

TYPE = ...

  • AZURE_CSE: 클라이언트 측 암호화(MASTER_KEY 값 필요).
  • NONE: 암호화 없음.

MASTER_KEY = '*string*' (AZURE_CSE 암호화에만 적용) 파일을 암호화하는 데 사용되는 클라이언트 측 마스터 키를 지정해요. 마스터 키는 Base64로 인코딩된 128비트 또는 256비트 키여야 해요.

선택 파라미터

PARTITION BY *expr* 언로드된 테이블 행을 별도 파일로 분할하는 데 사용되는 식을 지정해요. 문자열로 평가되는 모든 SQL 식을 지원해요.

언로드 작업은 파티션 식을 기준으로 테이블 행을 분할하고, 데이터 양과 병렬 작업 수를 기준으로 만들 파일 수를 결정하며, 이를 웨어하우스의 컴퓨트 리소스에 분산해요.

파일 이름에는 data_ 접두사가 붙고 파티션 열 값이 포함돼요. 각 파티션의 개별 파일 이름은 UUID(Universally Unique Identifier)로 식별돼요. UUID는 데이터 파일을 언로드하는 데 사용된 COPY 문의 쿼리 ID예요.

COPY INTO 문은 파티션 열 값을 언로드된 파일 이름에 기록해요. Snowflake는 잠재적으로 민감한 문자열 또는 정수 값보다 날짜나 타임스탬프 같은 공용 데이터 유형으로 데이터를 파티셔닝할 것을 권장해요. 파일 URL은 Snowflake가 유지 관리하는 내부 로그에 포함되므로, PARTITION BY 식에 참조된 열의 데이터도 내부 로그에 간접적으로 저장된다는 점에 유의하세요. 이 로그는 배포 지역 밖에서 처리될 수 있어요. 따라서 모범 사례로 PARTITION BY 식에는 날짜, 타임스탬프, 부울 데이터 유형만 포함하세요.

Snowflake는 데이터 언로드 작업을 더 제한하는 파라미터 세트를 제공해요:

  • PREVENT_UNLOAD_TO_INLINE_URL: 클라우드 저장소 URL과 접근 설정을 문에 직접 지정하는 외부 클라우드 저장소 위치로의 임시 데이터 언로드 작업을 방지해요.
  • PREVENT_UNLOAD_TO_INTERNAL_STAGES: 사용자 스테이지, 테이블 스테이지 또는 이름 있는 내부 스테이지를 포함한 모든 내부 스테이지로의 데이터 언로드 작업을 방지해요.

PARTITION BY와 함께 사용할 수 없는 다음 copy 옵션 값들에 유의하세요:

  • OVERWRITE = TRUE
  • SINGLE = TRUE
  • INCLUDE_QUERY_ID = FALSE

PARTITION BY와 함께 SQL 문에 ORDER BY 절을 포함해도 언로드된 파일에 지정된 순서가 보존된다는 보장은 없어요.

PARTITION BY 식이 NULL로 평가되면 출력 파일 이름의 파티션 경로는 _NULL_이에요 (예: mystage/_NULL_/data_01234567-0123-1234-0000-000000001234_01_0_0.snappy.parquet).

PARQUET 유형의 파일로 언로드할 때:

  • 병렬 실행 스레드가 언로드한 작은 데이터 파일은 MAX_FILE_SIZE copy 옵션 값과 최대한 가깝게 일치하는 단일 파일로 자동 병합돼요.
  • 모든 행 그룹은 128MB 크기예요. 행 그룹은 데이터를 행으로 논리적으로 수평 분할한 것이에요.
  • 언로드 작업은 MAX_FILE_SIZE copy 옵션 설정과 가능한 한 크기가 가까운 파일을 생성하려고 해요. 이 copy 옵션의 기본값은 16MB예요.
  • VARIANT 열은 단순 JSON 문자열로 변환돼요. TO_ARRAY 함수를 사용해 값을 배열로 캐스팅하면 JSON 문자열의 배열이 돼요.

언로드된 데이터 파일에서 파티션 식의 열을 생략하는 옵션은 없어요.

FILE_FORMAT = ( FORMAT_NAME = '*file_format_name*' ) 또는 FILE_FORMAT = ( TYPE = CSV | JSON | PARQUET [ ... ] ) 언로드된 데이터가 들어 있는 데이터 파일의 형식을 지정해요.

FORMAT_NAME = '*file_format_name*' 테이블에서 데이터를 언로드하는 데 사용할 기존의 이름 있는 파일 형식을 지정해요. 이름 있는 파일 형식은 데이터 파일의 형식 유형(CSV, JSON, PARQUET)과 기타 형식 옵션을 결정해요. 자세한 내용은 CREATE FILE FORMAT을 참고하세요.

TYPE = CSV | JSON | PARQUET 테이블에서 언로드되는 파일의 유형을 지정해요. 형식 유형을 지정하면 형식별 추가 옵션을 지정할 수 있어요.

  • JSON은 VARIANT 유형의 열(즉 JSON 데이터를 포함하는 열)에서만 데이터를 언로드하는 데 사용할 수 있어요.
  • 현재 VARIANT 열의 중첩 데이터는 Parquet 형식으로 성공적으로 언로드할 수 없어요.

copyOptions 언로드된 데이터에 대한 하나 이상의 copy 옵션을 지정해요.

VALIDATION_MODE = RETURN_ROWS COPY 명령이 데이터를 지정된 클라우드 저장소 위치로 언로드하는 대신 SQL 문의 쿼리 결과를 반환하도록 지시하는 문자열(상수)이에요. 지원되는 유일한 검증 옵션은 RETURN_ROWS예요. 이 옵션은 쿼리가 생성한 모든 행을 반환해요. 쿼리를 검증했으면 VALIDATION_MODE를 제거해 언로드 작업을 수행하면 돼요.

HEADER = TRUE | FALSE 출력 파일에 테이블 열 제목을 포함할지 지정해요.

  • TRUE로 설정하면 테이블 열 제목을 출력 파일에 포함해요. COPY 작업이 데이터를 여러 파일로 언로드하면 열 제목이 모든 파일에 포함돼요. Parquet 형식으로 데이터를 언로드할 때 테이블 열 이름은 출력 파일에 유지돼요.
  • FALSE로 설정하면: CSV 출력 파일에 테이블 열 제목을 포함하지 않아요. Parquet 출력 파일에 일반 열 제목(예: col1, col2 등)을 포함해요.

기본값: FALSE

형식 유형 옵션 (formatTypeOptions)

지정된 파일 형식 유형(FILE_FORMAT = ( TYPE = ... ))에 따라 하나 이상의 형식별 옵션을 포함할 수 있어요.

TYPE = CSV

COMPRESSION = AUTO | GZIP | BZ2 | BROTLI | ZSTD | DEFLATE | RAW_DEFLATE | NONE 언로드된 데이터 파일을 지정된 압축 알고리즘으로 압축하도록 지정하는 문자열(상수)이에요.

지원 값 참고
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 문이 여러 번 실행될 때 대상 스테이지에서 데이터 중복을 방지하는 데 도움이 돼요. 그러나 언로드 작업이 스테이지에 여러 파일을 쓸 때 Snowflake는 병렬 실행 스레드에 걸쳐 각 파일 이름이 고유함을 보장하는 접미사를 추가해요(예: 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';

더 알아보기 (Learn more)