versions 속성

versions 속성

versions 속성은 버전이 있는 모델(versioned model)의 버전 목록을 정의해요. 각 버전은 v 식별자를 가지며, dbt Mesh의 모델 거버넌스 기능으로 시간에 따른 모델 변경을 추적하고 관리할 수 있게 해 줘요.

출처: 문서

본문

모델 버전, dbt_project.yml 버전, .yml 버전 구분하기 — docs 사이트에서 "version"이라는 단어는 여러 곳에서 서로 다른 의미로 쓰여요:

  • Model versions — 시간에 따른 모델 변경을 추적·관리할 수 있게 해 주는 dbt Mesh 기능으로, 더 나은 거버넌스와 데이터 모델 관리를 지원해요.
  • dbt_project.yml version (선택) — dbt_project.yml 버전은 Mesh와 무관하며, dbt 프로젝트가 특정 dbt 버전과의 호환성을 나타내요.
  • .yml 속성 파일 version (선택) — .yml 속성 파일 안의 버전 번호는 dbt가 해당 YAML 파일을 어떻게 파싱하는지 알려줘요. Mesh와 무관해요.

models/<schema>.yml

models:
  - name: model_name
    versions:
      - v: <version_identifier> # required
        defined_in: <file_name> # optional -- default is <model_name>_v<v>
        columns:
          # specify all columns, or include/exclude columns from the top-level model YAML definition
          - include: <include_value>
            exclude: <exclude_list>
          # specify additional columns
          - name: <column_name> # required
      - v: ...
    
    # optional
    latest_version: <version_identifier> 

모델 버전 이름을 짓는 표준 규칙은 <model_name>_v<v>예요. 이 규칙은 dbt가 모델 정의(SQL 또는 Python)를 기대하는 파일과, 데이터베이스에 모델을 구체화할 때 기본적으로 사용하는 별칭(alias) 모두에 적용돼요.

v

모델 버전의 버전 식별자예요. 숫자(정수 또는 실수)나 어떤 문자열이든 될 수 있어요. 버전 식별자 값은 모델 버전들의 상대적 순서를 정하는 데 사용돼요. 버전 모델이 latest_version을 명시적으로 구성하지 않는 경우, 가장 높은 버전 번호가 최신 버전이 되어 version 인자 없이 모델을 가리키는 ref 호출을 해석해요. 일반적으로 모델에는 간단한 "메이저 버저닝(major versioning)" 체계를 권장해요: 1, 2, 3처럼요. 각 버전은 이전 버전과의 브레이킹 체인지(breaking change)를 반영하죠. 다른 버저닝 체계를 사용할 수도 있어요. 값이 모두 숫자가 아니면 dbt는 버전 식별자를 알파벳순으로 정렬해요. 버전 식별자에 v 글자를 넣지 마세요 — dbt가 알아서 붙여 주니까요. 여러 버전이 있는 모델을 실행하려면 --select 플래그를 사용할 수 있어요. 자세한 내용과 구문은 Model versions를 참고해 주세요.

defined_in

모델 버전이 정의된 모델 파일의 이름(확장자 예: .sql, .py 제외)이에요. defined_in을 지정하지 않으면 dbt는 <model_name>_v<v>라는 이름의 모델 파일에서 버전 모델의 정의를 검색해요. 모델의 최신 버전은 버전 접미사 없이 <model_name> 파일에 정의될 수도 있어요. 모델 파일 이름은 전역적으로 고유해야 해요 — 다른 이름의 모델 버전 구현을 정의할 때도 마찬가지예요.

alias

버전 모델의 기본 해석 alias<model_name>_v<v>예요. 이 로직은 generate_alias_name 매크로에 인코딩돼 있어요. 이 기본값은 두 가지 방법으로 덮어쓸 수 있어요:

  • 버전 yaml 또는 버전 모델 정의 안에서 커스텀 alias를 구성하기
  • node.version에 따라 다른 동작을 하도록 dbt의 generate_alias_name 매크로를 덮어쓰기

자세한 내용은 "Custom aliases"를 참고해 주세요. defined_in 값과 모델의 alias 구성은 규칙에 의해서만 조정되고, 둘은 독립적으로 선언·결정된다는 점을 기억하세요.

include

모델의 최상위 columns 속성에 정의된 컬럼 중, 해당 모델의 버전 구현에서 포함하거나 제외할 컬럼을 지정해요.

  • include는 다음 중 하나예요:
    • 포함할 특정 컬럼 이름의 목록
    • '*' 또는 'all' — 최상위 columns 속성의 모든 컬럼을 버전 모델에 포함시킨다는 의미
  • exclude는 제외할 컬럼 이름의 목록이에요. include'*' 또는 'all' 중 하나로 설정된 경우에만 선언할 수 있어요.

tip — 모델 선택에 사용하는 --select/--exclude 구문과 혼동하지 마세요.

버전 모델의 columns 목록은 최대 하나의 include/exclude 요소를 가질 수 있어요. 하지만 어떤 모델 버전도 컬럼을 지정하지 않는다면 컬럼을 정의할 필요가 없고, 버전 모델에서 columns/include/exclude 키를 생략하면 돼요. 이 경우 dbt는 모든 버전에 대해 최상위 컬럼을 자동으로 전부 사용해요. 버전의 columns 목록 안에 추가 컬럼을 선언할 수도 있어요. 버전 전용 컬럼의 name이 최상위에서 포함된 컬럼과 일치하면, 버전 전용 항목이 그 버전의 해당 컬럼을 덮어써요. models/<schema>.yml

models:
  
  # top-level model properties
  - name: <model_name>
    columns:
      - name: <column_name> # required
    
    # versions of this model
    versions:
      - v: <version_identifier> # required
        columns:
          - include: '*' | 'all' | [<column_name>, ...]
            exclude:
              - <column_name>
              - ... # declare additional column names to exclude
          
          # declare more columns -- can be overrides from top-level, or in addition
          - name: <column_name>
            ...

기본적으로 include는 "all", exclude는 빈 목록이에요. 결과적으로 기본 모델의 모든 컬럼이 버전 모델에 포함돼요.

Example

models/customers.yml

models:
  - name: customers
    columns:
      - name: customer_id
        description: Unique identifier for this table
        data_type: text
        constraints:
          - type: not_null
        data_tests:
          - unique
      - name: customer_country
        data_type: text
        description: "Country where the customer currently lives"
      - name: first_purchase_date
        data_type: date
    
    versions:
      - v: 4
      
      - v: 3
        columns:
          - include: "*"
          - name: customer_country
            data_type: text
            description: "Country where the customer first lived at time of first purchase"
      
      - v: 2
        columns:
          - include: "*"
            exclude:
              - customer_country
      
      - v: 1
        columns:
          - include: []
          - name: id
            data_type: int

v4columns를 지정하지 않았으므로 최상위 columns를 모두 포함해요. 나머지 각 버전은 최상위 속성에서 수정을 선언했어요:

  • v3는 모든 컬럼을 포함하지만, customer_country 컬럼을 다른 description으로 다시 구현해요.
  • v2customer_country 제외 모든 컬럼을 포함해요.
  • v1은 최상위 columns전혀 포함하지 않고, 대신 id라는 단일 정수 컬럼만 선언해요.

Our recommendations

(dbt v1.12 이상 적용)

  • 모델 버전과 별칭에 일관된 명명 규칙을 따라 주세요.
  • defined_inalias는 충분한 이유가 있을 때만 사용하세요.
  • latest_version_pointer 구성을 사용해 모델의 최신 버전을 가리키는 뷰를 자동 생성하세요. 모델별로 활성화하거나 dbt_project.ymllatest_version_pointer_enabled_by_default 플래그로 전역 활성화할 수 있어요.

Detecting breaking changes

Slim CI에서 state:modified 선택 메서드를 사용하면 dbt가 버전 모델 계약의 변경을 감지하고, 다운스트림 소비자에게 브레이킹이 될 수 있는 변경이 있으면 에러를 발생시켜요. 브레이킹 체인지에는 다음이 포함돼요:

  • 기존 컬럼 제거
  • 기존 컬럼의 data_type 변경
  • 기존 컬럼의 constraints 중 하나 제거·수정 (dbt v1.6 이상)
  • 버전이 없는 계약 모델 변경

dbt는 또한 모델이 계약을 갖고 있거나 가졌는데 버전이 없는 경우 경고해요.

  • 버전 없는 모델 예시 메시지:
  Breaking Change to Unversioned Contract for contracted_model (models/contracted_models/contracted_model.sql)
  While comparing to previous project state, dbt detected a breaking change to an unversioned model.
    - Contract enforcement was removed: Previously, this model's configuration included contract: {enforced: true}. It is no longer configured to enforce its contract, and this is a breaking change.
    - Columns were removed:
      - color
      - date_day
    - Enforced column level constraints were removed:
      - id (ConstraintType.not_null)
      - id (ConstraintType.primary_key)
    - Enforced model level constraints were removed:
      - ConstraintType.check -> ['id']
    - Materialization changed with enforced constraints:
      - table -> view
  • 버전 모델 예시 메시지:
Breaking Change to Contract Error in model sometable (models/sometable.sql)
  While comparing to previous project state, dbt detected a breaking change to an enforced contract.
  The contract's enforcement has been disabled.
  Columns were removed:
   - order_name
  Columns with data_type changes:
   - order_id (number -> int)
  Consider making an additive (non-breaking) change instead, if possible.
  Otherwise, create a new model version: https://docs.getdbt.com/docs/mesh/govern/model-versions

추가(비브레이킹) 변경은 브레이킹으로 간주되지 않아요:

  • 계약 모델에 새 컬럼 추가
  • 계약 모델의 기존 컬럼에 새 constraints 추가

더 알아보기 (Learn more)