hard_deletes

hard_deletes (하드 삭제 처리)

hard_deletes 설정은 소스에서 삭제된 행을 스냅샷이 어떻게 처리할지를 제어해요. dbt v1.9부터 사용할 수 있고, ignore(기본값), invalidate, new_record 세 가지 방법을 지원해요. dbt-postgres, dbt-bigquery, dbt-snowflake, dbt-redshift 어댑터에서 쓸 수 있어요.

출처: dbt 공식 문서

본문

설정 방법

snapshots/schema.yml

snapshots:
  - name: <snapshot_name>
    config:
      hard_deletes: 'ignore' | 'invalidate' | 'new_record'

dbt_project.yml

snapshots:
  <resource-path>:
    +hard_deletes: "ignore" | "invalidate" | "new_record"

snapshots/.sql

{{
    config(
        unique_key='id',
        strategy='timestamp',
        updated_at='updated_at',
        hard_deletes='ignore' | 'invalidate' | 'new_record'
    )
}}

설명

hard_deletes 설정으로 소스에서 삭제된 행을 어떻게 다룰지 더 세밀하게 제어할 수 있어요. 지원하는 옵션은 ignore(기본값), invalidate(이전 invalidate_hard_deletes=true를 대체), 그리고 new_record예요. new_record를 쓰면 스냅샷 테이블에 새 메타데이터 컬럼이 하나 생긴다는 점에 주의해요.

hard_deletes는 dbt-postgres, dbt-bigquery, dbt-snowflake, dbt-redshift 어댑터에서 사용할 수 있어요.

hard_deletes와 invalidate_hard_deletes 설정은 언제 쓰나요?

invalidate_hard_deletes(v1.8 이하)를 쓰면 좋은 경우:

  • 스냅샷 기록에 공백(삭제된 행에 대한 레코드 누락)이 있어도 괜찮을 때.
  • 삭제된 행의 dbt_valid_to 타임스탬프를 현재 시간으로 설정해 무효화(암묵적 삭제)하고 싶을 때.
  • 삭제를 별도 상태로 추적할 필요가 없는 작은 데이터셋을 다룰 때.

hard_deletes: new_record(v1.9 이상)를 쓰면 좋은 경우:

  • 공백 없는 연속적인 스냅샷 기록을 유지하고 싶을 때.
  • dbt_is_deleted 컬럼이 있는 새 행을 추가해 삭제를 명시적으로 추적하고 싶을 때(명시적 삭제).
  • 삭제된 레코드를 명시적으로 추적하는 게 데이터 계보(lineage)를 더 명확하게 만드는 더 큰 데이터셋을 다룰 때.

경고

기존 스냅샷을 hard_deletes 설정을 쓰도록 바꾸면 dbt가 마이그레이션을 자동으로 처리하지 않아요. 새로 만드는 스냅샷에만 이 설정을 쓰거나, 이 설정을 활성화하기 전에 기존 테이블의 업데이트를 미리 준비해 두는 걸 권장해요.

기본값

hard_deletes를 지정하지 않으면 기본적으로 ignore로 동작해요. 삭제된 행은 추적되지 않고, 그 dbt_valid_to 컬럼은 NULL로 남아요.

hard_deletes 설정은 세 가지 방법을 가져요.

메서드 설명
ignore (기본값) 삭제된 레코드에 아무 조치도 하지 않아요.
invalidate 기존 invalidate_hard_deletes=true와 동일하게 동작해요. 삭제된 레코드는 dbt_valid_to를 현재 시간으로 설정해 무효화돼요. 이 메서드는 invalidate_hard_deletes 설정을 대체해 소스의 삭제 행을 처리하는 방식을 더 유연하게 만들어요.
new_record 레코드가 삭제될 때 dbt_is_deleted 메타 필드를 사용해 삭제된 레코드를 새 행으로 추적해요.

고려 사항

  • 하위 호환성: invalidate_hard_deletes 설정은 기존 스냅샷에서는 여전히 지원되지만, hard_deletes와 함께 쓸 수는 없어요.
  • 새 스냅샷: 새 스냅샷에는 invalidate_hard_deletes 대신 hard_deletes를 사용하는 걸 권장해요.
  • 마이그레이션: 데이터를 마이그레이션하지 않고 기존 스냅샷을 hard_deletes로 전환하면, 옛 데이터 형식과 새 데이터 형식이 섞이는 등 일관되지 않거나 잘못된 결과가 나올 수 있어요.

예시

snapshots/schema.yml

snapshots:
  - name: my_snapshot
    config:
      hard_deletes: new_record  # options are: 'ignore', 'invalidate', or 'new_record'
      strategy: timestamp
      updated_at: updated_at
    columns:
      - name: dbt_valid_from
        description: Timestamp when the record became valid.
      - name: dbt_valid_to
        description: Timestamp when the record stopped being valid.
      - name: dbt_is_deleted
        description: Indicates whether the record was deleted.

결과 스냅샷 테이블은 hard_deletes: new_record 설정을 반영해요. 레코드가 삭제됐다가 다시 복원되면 결과 스냅샷 테이블은 다음과 같이 보일 수 있어요.

id dbt_scd_id Status dbt_updated_at dbt_valid_from dbt_valid_to dbt_is_deleted
1 60a1f1dbdf899a4dd... pending 2024-10-02 ... 2024-05-19... 2024-05-20 ... False
1 b1885d098f8bcff51... pending 2024-10-02 ... 2024-05-20 ... 2024-06-03 ... True
1 b1885d098f8bcff53... shipped 2024-10-02 ... 2024-06-03 ... False
2 b1885d098f8bcff55... active 2024-10-02 ... 2024-05-19 ... False

이 예시에서 레코드가 삭제되면 dbt_is_deleted 컬럼이 True가 되고, 레코드가 복원되면 dbt_is_deleted 컬럼이 False로 설정돼요.

더 알아보기 (Learn more)