EXECUTE DCM PROJECT
EXECUTE DCM PROJECT
DCM(Database Change Management) 프로젝트에 대해 다음 작업 중 하나를 실행하는 명령이에요. DCM 프로젝트는 정의 파일을 통해 데이터베이스 객체 변경을 버전 관리하고 배포하는 객체예요.
출처: 문서
본문
EXECUTE DCM PROJECT <name>은 다음 작업을 수행해요:
EXECUTE DCM PROJECT <name> PLAN— DCM 프로젝트의 드라이 런(dry run)을 수행하여 배포 중에 대상에 적용될 변경 사항을 분석하지만, 변경 사항을 적용하지는 않아요.EXECUTE DCM PROJECT <name> PLAN DELTA— 마지막 배포 이후 변경된 정의와 그에 의존하는 다운스트림 정의만 평가하는 더 빠른 드라이 런.EXECUTE DCM PROJECT <name> DEPLOY— 프로젝트의 정의 파일에 정의된 변경 사항을 계정에 배포해요.EXECUTE DCM PROJECT <name> TEST ALL— DCM 프로젝트가 관리하는 연결된 데이터 메트릭 함수의 모든 기대값(expectations)을 테스트해요.EXECUTE DCM PROJECT <name> PREVIEW— 지정된 테이블, 뷰 또는 동적 테이블에 대해 소스 경로에 지정된 현재 정의의 데이터 샘플을 반환해요.EXECUTE DCM PROJECT <name> PURGE— DCM 프로젝트가 현재 관리하는 모든 엔티티를 삭제하고, 모든 권한 부여를 취소하고, 모든 연결을 제거해요.
구문 (Syntax)
EXECUTE DCM PROJECT <name>
PLAN [ DELTA ]
[ USING [ CONFIGURATION <config_name> ] [ (, <expr> [, <expr>, ...]) ] ]
FROM '<source_files_path>'
[ OUTPUT_PATH '<output_path>' ]
EXECUTE DCM PROJECT <name>
DEPLOY [ AS "<deployment_name_alias>" ]
[ USING [ CONFIGURATION <config_name> ] [ (, <expr> [, <expr>, ...]) ] ]
FROM '<source_files_path>'
EXECUTE DCM PROJECT <name>
TEST ALL
EXECUTE DCM PROJECT <name>
PREVIEW <fully_qualified_table_object_name>
USING CONFIGURATION <config_name>
FROM '<source_files_path>'
[ LIMIT <number_of_rows> ]
EXECUTE DCM PROJECT <name>
PURGE [ AS "<deployment_name_alias>" ]
필수 파라미터 (Required parameters)
- name — 실행할 DCM 프로젝트의 식별자를 지정해요. 식별자에 공백이나 특수 문자가 포함되면 전체 문자열을 큰따옴표로 묶어야 해요. 큰따옴표로 묶은 식별자는 대소문자를 구분해요.
- PLAN — DCM 프로젝트의 드라이 런을 수행하도록 Snowflake에 지시해요. 드라이 런의 경우 Snowflake는 배포 중에 대상에 적용될 변경 사항을 분석하지만 변경 사항을 적용하지는 않아요.
- PLAN DELTA — 마지막 배포 이후 변경된 정의와 그에 의존하는 프로젝트의 다운스트림 정의만 평가하는 더 빠른 드라이 런을 수행하도록 지시해요. 전체 PLAN과 달리 PLAN DELTA는 변경되지 않은 정의를 현재 계정 상태와 비교하지 않아요. 활발한 개발 중에 증분 변경에 대한 더 빠른 피드백을 얻으려면 PLAN DELTA를 사용해요. 변경되지 않은 정의를 건너뛰므로 마지막 배포 이후 계정에서 DCM 프로젝트 외부에서 발생한 변경(예: 다른 사용자가 삭제하거나 변경한 뷰)을 감지하지 못해요. 배포 전에는 항상 전체 PLAN을 실행하여 외부 변경이 배포 실패를 일으키지 않는지 확인해요.
- DEPLOY [ AS "deployment_name_alias" ] — 프로젝트의 정의 파일에 정의된 변경 사항을 계정에 배포해요. 선택적으로 배포의 별칭을 지정해요.
- FROM 'source_files_path' — DCM 프로젝트의 소스 파일이 포함된 디렉토리를 지정해요. 디렉토리는 manifest 파일과
/sources/definitions/에 최소한 하나의 정의 파일을 포함해야 해요. manifest 파일은 구성이 지정된 경우 템플릿 값을 제공해요. - TEST ALL — DCM 프로젝트가 현재 관리하는 테이블, 동적 테이블 또는 뷰에 연결된 모든 데이터 품질 기대값을 테스트해요.
- PREVIEW fully_qualified_table_object_name — 배포된 상태와 무관하게 지정된 테이블, 뷰 또는 동적 테이블에 대해 소스 경로에 지정된 현재 정의의 데이터 샘플을 반환해요.
- PURGE [ AS "deployment_name_alias" ] — 정의가 없는 배포를 실행하여 DCM 프로젝트가 현재 관리하는 모든 엔티티를 삭제하고, 모든 권한 부여를 취소하고, 모든 연결을 제거해요. 선택적으로 배포의 별칭을 지정해요.
경고: PURGE는 설계상 파괴적이에요. 주의해서 사용하고 개발 샌드박스나 데모 같은 비프로덕션 프로젝트에만 사용해요. PURGE는 DCM 프로젝트 자체를 삭제하지 않아요. purge 후 프로젝트 객체를 제거하려면
DROP DCM PROJECT를 실행해요. purge 실행은 DCM 프로젝트의 배포 기록에 나타나며, 명령이 성공적으로 실행되었는지 확인할 수 있어요.
선택 파라미터 (Optional parameters)
- USING CONFIGURATION config_name — 사용할 구성을 지정해요. 이렇게 하면 서로 다른 프로젝트 정의 파일을 사용하지 않고도 개발, 스테이징, 프로덕션 같은 다양한 환경에 맞게 배포를 사용자 지정할 수 있어요. 구성 이름이 모두 대문자가 아니면 큰따옴표로 묶어요.
- USING ( expr [, expr , ... ] ) — 템플릿 변수 값을 선택적으로 지정해요. 이 옵션을 사용하면 이 특정 변수에 대한 기본값이나 구성 값을 재정의해요. 단일 표현식은
<variable_name> => <variable_value>형태여야 해요. 목록의 경우<variable_name> => [<value1>, <value2>, ...]형태를 사용해요. 예:wh_size => 'MEDIUM'또는teams => ['TEAM_A', 'TEAM_B']. - OUTPUT_PATH 'output_path' — Snowflake가 PLAN 실행의 렌더링된 프로젝트 정의와 원시 변경 세트(raw changeset)를 쓰는 디렉토리를 지정해요. 디렉토리가 없으면 Snowflake가 만듭니다. OUTPUT_PATH를 지정하는 각 PLAN 실행은 그 디렉토리의 이전 렌더링 출력을 덮어써요.
- LIMIT number_of_rows — PREVIEW가 반환하는 행 수를 제한해요.
접근 제어 요구사항 (Access control requirements)
이 작업을 실행하는 역할은 최소한 다음 권한을 가져야 해요:
| Privilege | Object | Notes |
|---|---|---|
| OWNERSHIP | DCM project | OWNERSHIP은 객체 생성 역할에 자동 부여되는 특수 권한이지만, 소유 역할(또는 MANAGE GRANTS 권한이 있는 역할)이 GRANT OWNERSHIP 명령으로 다른 역할에 이전할 수도 있어요. |
스키마에서 객체를 운영하려면 부모 데이터베이스에 대한 권한이 하나 이상, 부모 스키마에 대한 권한이 하나 이상 필요해요.
출력 (Output)
DCM 프로젝트가 실행된 후 이 명령은 변형에 따라 다음 출력을 반환해요:
- PLAN, DEPLOY, PURGE: 변경 로그가 포함된 JSON 객체를 가진 단일 행. PURGE는 빈 배포로 실행되므로 출력은 DEPLOY와 동일하며, 모든 관리 엔티티가 DROP으로 보고돼요.
- PREVIEW: 결과 집합.
- TEST ALL: 전체 응답을 포함하는 JSON 객체를 가진 단일 행.
PLAN 및 DEPLOY 출력
표준 plan 출력은 JSON 형식으로 plan 실행에 대한 다음 정보를 포함해요:
{
"version": 2,
"metadata": {
"timestamp": <timestamp>,
"query_id": <query_id>,
"project_name": <project_name>,
"user": <user>,
"role_name": <role_name>,
"command": <command>
},
"changeset": [
{
"type": <type>,
"object_id": {
"domain": <domain>,
"name": <name>,
"fqn": <fqn>,
"database": <database>,
"schema": <schema>
},
"changes": [
{
"kind": <kind>,
"attribute_name": <attribute_name>,
"value": <value>,
"changes": [
{
"kind": <kind>,
"attribute_name": <attribute_name>,
"value": <value>
}
]
}
]
}
]
}
| Property | Description |
|---|---|
| version | 출력 형식의 스키마 버전. 버전 2가 최신이며 유일하게 지원되는 버전이에요. |
| metadata | 실행에 대한 컨텍스트 정보. |
| metadata.timestamp | 명령이 실행된 ISO 8601 타임스탬프. |
| metadata.query_id | 이 plan을 생성한 쿼리의 고유 식별자. |
| metadata.project_name | DCM Project 객체의 정규화된 이름. |
| metadata.user | 명령을 실행한 사용자의 이름. |
| metadata.role_name | 명령을 실행하는 데 사용된 활성 역할. |
| metadata.command | 실행된 명령. PLAN 또는 DEPLOY. |
| changeset | 변경 항목의 배열. 각 항목은 생성, 변경 또는 삭제되었거나 될 하나의 객체를 나타내요. 빈 배열은 프로젝트 정의가 이미 계정과 동기화되었음을 나타내요. |
| changeset[].type | 객체에 대한 계획된 작업. 가능한 값: CREATE, ALTER, DROP. |
| changeset[].object_id | 대상 객체를 식별해요. |
| changeset[].object_id.domain | Snowflake 객체 유형. |
| changeset[].object_id.name | 객체의 이름. |
| changeset[].object_id.fqn | 객체의 정규화된 이름. |
| changeset[].object_id.database | 객체를 포함하는 데이터베이스. 계정 수준 객체에서는 생략돼요. |
| changeset[].object_id.schema | 객체를 포함하는 스키마. 데이터베이스 수준 및 계정 수준 객체에서는 생략돼요. |
| changeset[].changes | 특정 속성 수정을 자세히 설명하는 변경 설명자의 배열. |
| changeset[].changes[].kind | 변경의 유형. 가능한 값: set, changed, unset, nested, collection. kind의 값이 객체의 나머지 키를 결정해요. |
| changeset[].changes[].attribute_name | 설정되거나 변경되는 속성의 이름. kind가 set, changed, unset일 때 존재해요. |
| changeset[].changes[].value | 속성의 새 값. kind가 set 또는 changed일 때 존재해요. |
| changeset[].changes[].prev_value | 변경 전 속성의 이전 값. kind가 changed일 때만 존재해요. |
| changeset[].changes[].collection_name | 수정 중인 컬렉션의 이름(예: columns, constraints, privileges, expectations). kind가 collection일 때만 존재해요. |
| changeset[].changes[].id_label | 컬렉션 내 항목을 식별하는 데 사용되는 레이블(예: name). 특정 컬렉션에서만 존재해요. |
| changeset[].changes[].changes | 컬렉션 항목 설명자의 중첩 배열. kind가 collection일 때만 존재해요. |
| changeset[].changes[].changes[].kind | 컬렉션 항목에 대한 변경 유형. 가능한 값: added, removed, modified. |
| changeset[].changes[].changes[].item_id | 컬렉션 내의 항목을 식별해요. 컬렉션 유형에 따라 문자열 또는 객체일 수 있어요. |
| changeset[].changes[].changes[].changes | 이 항목에 대한 추가 변경 설명자의 배열. added 및 modified 항목에 존재해요. removed 항목에는 항상 없어요. |
plan 출력의 예시:
{
"version": 2,
"metadata": {
"timestamp": <timestamp>,
"query_id": <query_id>,
"project_name": <project_name>,
"user": <user>,
"role_name": <role_name>,
"command": <command>
},
"changeset": [
{
"type": "CREATE",
"object_id": {
"domain": "TABLE",
"name": "CUSTOMER_SUMMARY",
"fqn": "MY_DB.ANALYTICS.CUSTOMER_SUMMARY",
"database": "MY_DB",
"schema": "ANALYTICS"
},
"changes": [
{
"kind": "set",
"attribute_name": "warehouse_size",
"value": "XSMALL"
},
{
"kind": "set",
"attribute_name": "query",
"value": "SELECT customer_id, SUM(amount) AS total FROM orders GROUP BY customer_id"
}
]
},
{
"type": "ALTER",
"object_id": {
"domain": "DYNAMIC_TABLE",
"name": "ORDER_DETAILS",
"fqn": "MY_DB.ANALYTICS.ORDER_DETAILS",
"database": "MY_DB",
"schema": "ANALYTICS"
},
"changes": [
{
"kind": "changed",
"attribute_name": "warehouse_size",
"value": "SMALL",
"prev_value": "XSMALL"
},
{
"kind": "collection",
"collection_name": "columns",
"id_label": "name",
"changes": [
{
"kind": "added",
"item_id": "DISCOUNT_AMOUNT",
"changes": [
{
"kind": "set",
"attribute_name": "data_type",
"value": "NUMBER(10,2)"
}
]
},
{
"kind": "modified",
"item_id": "ORDER_STATUS",
"changes": [
{
"kind": "changed",
"attribute_name": "data_type",
"value": "VARCHAR(50)",
"prev_value": "VARCHAR(20)"
}
]
},
{
"kind": "removed",
"item_id": "LEGACY_FLAG"
}
]
}
]
},
{
"type": "DROP",
"object_id": {
"domain": "VIEW",
"name": "OLD_REPORT_VIEW",
"fqn": "MY_DB.ANALYTICS.OLD_REPORT_VIEW",
"database": "MY_DB",
"schema": "ANALYTICS"
},
"changes": []
}
]
}
TEST ALL 출력
TEST 출력은 다음 형식으로 전체 상태와 값이 있는 기대값을 포함해요:
{
"status": <status>,
"expectations": [
{
"table_name": <table_name>,
...
}
]
}
| Property | Description |
|---|---|
| status | 테스트 실행의 전체 결과. 가능한 값: SUCCESSFUL(모든 기대값 충족), FAILED(하나 이상의 기대값 위반). |
| expectations[] | 평가된 각 데이터 품질 기대값에 하나씩, 기대값 결과의 배열. |
| table_name | 기대값이 평가된 테이블 또는 뷰의 정규화된 이름. |
| metric_database | 데이터 메트릭 함수를 포함하는 데이터베이스. |
| metric_schema | 데이터 메트릭 함수를 포함하는 스키마. |
| metric_name | 데이터 메트릭 함수의 이름(예: NULL_COUNT, MIN, UNIQUE_COUNT). |
| expectation_name | 프로젝트에 정의된 기대값의 이름. |
| expectation_expression | 메트릭 값이 평가되는 부울 표현식(예: value = 0, value >= 0). |
| value | 데이터 메트릭 함수 평가의 결과. expectation_violated가 false일 때만 존재해요. |
| expectation_violated | 기대값이 위반되었는지 여부. 메트릭 값이 기대 표현식을 충족하지 않으면 true, 그렇지 않으면 false. |
| column_names | 데이터 메트릭 함수가 평가된 열 이름의 배열. |
데이터 품질 테스트의 JSON 출력 예시:
{
"status": "FAILED",
"expectations": [
{
"table_name": "db.schema.my_table",
"metric_database": "SNOWFLAKE",
"metric_schema": "CORE",
"metric_name": "NULL_COUNT",
"expectation_name": "no_nulls_in_id",
"expectation_expression": "value = 0",
"value": 0,
"expectation_violated": false,
"column_names": ["ID"]
},
{
"table_name": "db.schema.my_table",
"metric_database": "SNOWFLAKE",
"metric_schema": "CORE",
"metric_name": "UNIQUE_COUNT",
"expectation_name": "unique_id_check",
"expectation_expression": "value >= 100",
"value": null,
"expectation_violated": true,
"column_names": ["ID"]
}
]
}
사용 메모 (Usage notes)
EXECUTE DCM PROJECT ... PLAN으로 DCM 프로젝트를 실행할 때 출력 구조와 시뮬레이션은 배포와 동일하지만 계정에 변경 사항이 적용되지 않아요. PLAN을 통해 렌더링된 정의 파일에 유효한 구문이 있는지, 현재 계정 상태가 어떤 변경을 생성할지, 프로젝트 소유자 역할에 필요한 권한이 있는지 확인할 수 있어요. DEPLOY는 저장된 PLAN 결과를 실행하지 않아요.
PLAN은 DEPLOY를 밀접하게 반영하므로 변경 사항이 적용되지 않더라도 DEPLOY와 동일한 DCM 프로젝트에 대한 OWNERSHIP 권한이 필요해요. 이렇게 하면 드라이 런이 배포 전에 권한 오류를 표면화해요.
의도하지 않은 변경을 피하고 오류를 잡으려면 DCM 프로젝트를 배포하기 전에 항상 EXECUTE DCM PROJECT PLAN을 실행해요.
템플릿 변수 지원 (Support for template variables)
템플릿 변수를 사용하면 DCM 프로젝트 실행 중 파라미터화된 정의 파일의 콘텐츠를 동적으로 선택할 수 있어요.
예시 (Examples)
기본 예시
변경 사항을 적용하지 않고 프로젝트의 변경을 검증하기 위해 PLAN 모드로 DCM 프로젝트를 실행해요:
EXECUTE DCM PROJECT my_project
PLAN
FROM '@my_database.my_schema.my_stage/my_project';
마지막 배포 이후 변경된 정의만 빠르게 검증하기 위해 PLAN DELTA 모드로 DCM 프로젝트를 실행해요:
EXECUTE DCM PROJECT my_project
PLAN DELTA
FROM '@my_database.my_schema.my_stage/my_project';
배포 별칭과 PROD라는 구성을 지정하기 위해 DEPLOY 모드로 DCM 프로젝트를 실행해요:
EXECUTE DCM PROJECT my_project
DEPLOY AS "my_update"
USING CONFIGURATION PROD
FROM '@my_database.my_schema.my_stage/my_project';
비프로덕션 DCM 프로젝트를 purge하여 현재 관리하는 모든 엔티티를 삭제하고, 모든 권한 부여를 취소하고, 모든 연결을 제거해요. 배포 기록의 항목에 레이블을 붙이는 별칭을 사용해요:
EXECUTE DCM PROJECT my_project PURGE AS "sandbox cleanup";
템플릿 변수 예시
다음 예시는 EXECUTE DCM PROJECT 문장에서 템플릿 변수의 값을 지정하는 방법을 보여줘요.
DCM 프로젝트의 manifest 파일에 정의된 템플릿 변수 재정의하기
- manifest 파일에
desc라는 템플릿 변수를 정의해요:
manifest_version: 2
type: DCM_PROJECT
default_target: DCM_DEV
targets:
DCM_DEV:
account_identifier: MYORG-MYACCOUNT
project_name: MY_DB.MY_SCHEMA.MY_PROJECT
project_owner: DCM_PROJECT_OWNER
templating_config: FIRST_CONFIG
templating:
defaults:
desc: "created by hello world project"
configurations:
FIRST_CONFIG: {}
- 템플릿 변수를 사용하는 정의 파일을 만들어요:
DEFINE DATABASE NEW_DB;
DEFINE TABLE NEW_DB.PUBLIC.TBL (ID INT) COMMENT = '{{desc}}';
- DEPLOY 모드로
EXECUTE DCM PROJECT명령을 호출하고, manifest의 기본값을 재정의하기 위해 desc 변수의 값을 지정해요:
EXECUTE DCM PROJECT MY_PROJECT DEPLOY
USING CONFIGURATION FIRST_CONFIG (desc => 'This object is mine')
FROM '@my_database.my_schema.my_stage/my_project';
manifest 파일에 정의되지 않은 템플릿 변수에 값 제공하기
- 원하는 명령으로 정의 파일을 만들어요:
DEFINE DATABASE NEW_DB;
DEFINE TABLE NEW_DB.PUBLIC.TBL (ID INT) COMMENT = '{{desc_new}}';
EXECUTE DCM PROJECT명령을 호출하고 desc_new 변수의 값을 지정해요:
EXECUTE DCM PROJECT MY_PROJECT PLAN
USING (desc_new => 'This object is mine')
FROM '@my_database.my_schema.my_stage/my_project';