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';

더 알아보기 (Learn more)