๐Ÿ“’ DBT(2)

Kimdongkiยท2024๋…„ 6์›” 8์ผ

DBT

๋ชฉ๋ก ๋ณด๊ธฐ
2/2

๐Ÿ“ŒDBT Seeds

  • ๋งŽ์€ dimension ํ…Œ์ด๋ธ”๋“ค์€ ํฌ๊ธฐ๊ฐ€ ์ž‘๊ณ  ๋งŽ์ด ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • Seeds๋Š” ์ด๋ฅผ ํŒŒ์ผ ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ์›จ์–ดํ•˜์šฐ์Šค๋กœ ๋กœ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
    -> Seeds๋Š” ์ž‘์€ ํŒŒ์ผ ๋ฐ์ดํ„ฐ๋ฅผ์ง€์นญํ•œ๋‹ค (๋ณดํ†ต csvํŒŒ์ผ)
  • 'dbt seed'๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด์„œ ๋นŒ๋“œํ•œ๋‹ค.

๐Ÿ“ŒDBT Sources

1. Staging ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค ๋•Œ ์ž…๋ ฅ ํ…Œ์ด๋ธ”๋“ค์ด ์ž์ฃผ ๋ฐ”๋€๋‹ค๋ฉด?

  • models ์•„๋ž˜ .sql ํŒŒ์ผ๋“ค์„ ์ผ์ผ์ด ์ฐพ์•„ ๋ฐ”๊พธ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • ์ด ๋ฒˆ๊ฑฐ๋กœ์›€์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด Sources์ด๋‹ค.
    -> ์ž…๋ ฅ ํ…Œ์ด๋ธ”์— ๋ณ„์นญ์„ ์ฃผ๊ณ  ๋ณ„์นญ์„ staging ํ…Œ์ด๋ธ”์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

2. Sources ์†Œ๊ฐœ

  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฒ˜์Œ ์ž…๋ ฅ ๋˜๋Š” ETL ํ…Œ์ด๋ธ”์„ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค.

    • ๋ณ„์นญ ์ œ๊ณต
    • ์ตœ์‹  ๋ ˆ์ฝ”๋“œ ์ฒดํฌ ๊ธฐ๋Šฅ ์ œ๊ณต
  • ํ…Œ์ด๋ธ” ์ด๋ฆ„๋“ค์— ๋ณ„๋ช…(alias)์„ ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

    • ์ด๋ฅผ ํ†ตํ•ด ETL๋‹จ์˜ ์†Œ์Šค ํ…Œ์ด๋ธ”์ด ๋ฐ”๋€Œ์–ด๋„ ๋’ค์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.
    • ์ถ”์ƒํ™”๋ฅผ ํ†ตํ•œ ๋ณ€๊ฒฝ์ฒ˜๋ฆฌ๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
    • ์ด ๋ณ„๋ช…์€ source ์ด๋ฆ„๊ณผ ์ƒˆ ํ…Œ์ด๋ธ” ์ด๋ฆ„์˜ ๋‘ ๊ฐ€์ง€๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
      -> ex) raw_data.user_metadata -> urface, metadata
  • Source ํ…Œ์ด๋ธ”๋“ค์— ์ƒˆ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š”์ง€ ์ฒดํฌํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•œ๋‹ค.

3. ์‹ค์Šต

  • models/sources.yml ์ƒ์„ฑ
version: 2

sources:
	- name: urface
	    schema: raw_data
    tables:
    	- name: metadata
        	identifier: user_metadata
        - name: event
        	identifier: user_event
        - name: variant
        	identifier: user_variant
  • raw_data.user_metadata๋Š” Jinja์—์„œ source("urface", "metadata")๋กœ ์ง€์นญ๋œ๋‹ค.

  • ์•„๋ž˜๋Š” src_user_event.sql์˜ ์˜ˆ์‹œ์ด๋‹ค.
    -> models ์•„๋ž˜์˜ ๋‹ค๋ฅธ ํŒŒ์ผ๋“ค๋„ ์ ์ ˆํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•ด์•ผํ•œ๋‹ค.

WITH src_user_event AS(
	SELECT * FROM {{ source("urface", "event") }}
)
SELECT
	 user_id,
     ....
     
FROM
	src_user_event

4. Sources ์ตœ์‹ ์„ฑ(Freshness)

  • ํŠน์ • ๋ฐ์ดํ„ฐ๊ฐ€ ์†Œ์Šค์™€ ๋น„๊ตํ•ด์„œ ์–ผ๋งˆ๋‚˜ ์ตœ์‹ ์„ฑ์ด ๋–จ์–ด์ง€๋Š”์ง€ ์ฒดํฌํ•˜๋Š” ๊ธฐ๋Šฅ
  • dbt source freshness ๋ช…๋ น์–ด๋กœ ์‹คํ–‰
  • ์ด๋ฅผ ํ•˜๋ ค๋ฉด mldels/sources.yml์˜ ํ•ด๋‹น ํ…Œ์ด๋ธ” ๋ฐ‘์— ์•„๋ž˜๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค.
tables:
	- name: event
    	identifier: user_event
        loaded_at_field: datastamp
        freshness:
        	warn_after: { count: 1, period: hour }
            error_after: { count: 24, period: hour }

-> ์ง€๊ธˆ raw_data.user_event ํ…Œ์ด๋ธ”์—์„œ datestamp์˜ ์ตœ๋Œ€๊ฐ’์ด ํ˜„์žฌ ์‹œ๊ฐ„๋ณด๋‹ค 1์‹œ๊ฐ„ ์ด์ƒ ๋’ค์ณ์ € ์žˆ์ง€๋งŒ 24์‹œ๊ฐ„์ด ์•„๋‹ˆ๋ผ๋ฉด Warning, 24์‹œ๊ฐ„ ์ด์ƒ์ด๋ผ๋ฉด ERROR


๐Ÿ“Œ DBT Snapshots

  • Dimension ํ…Œ์ด๋ธ”์€ ์„ฑ๊ฒฉ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ์ด ์ž์ฃผ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค
  • bt์—์„œ๋Š” ํ…Œ์ด๋ธ”์˜ ๋ณ€ํ™”๋ฅผ ๊ณ„์†์ ์œผ๋กœ ๊ธฐ๋กํ•จ์œผ๋กœ์จ ๊ณผ๊ฑฐ ์–ด๋А์‹œ์ ์ด๊ฑด ๋‹ค์‹œ ๋Œ์•„๊ฐ€์„œ ํ…Œ์ด๋ธ”์˜ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๋งํ•œ๋‹ค.
    • ์ด๋ฅผ ํ†ตํ•ด ํ…Œ์ด๋ธ”์— ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ๊ณผ๊ฑฐ ๋ฐ์ดํ„ฐ๋กœ ๋กค๋ฐฑ ๊ฐ€๋Šฅํ•˜๋‹ค.
    • ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๊ด€๋ จ ๋ฌธ์ œ ๋””๋ฒ„๊น…๋„ ์‰ฌ์›Œ์ง„๋‹ค.

1. SCD Type 2์™€ DBT

  • Dimension ํ…Œ์ด๋ธ”์—์„œ ํŠน์ • entity์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ
    -> ex) employee_jobs ํ…Œ์ด๋ธ”
    • ํŠน์ • employee_id์˜ job_code๊ฐ€ ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ
    • ๋ณ€๊ฒฝ์‹œ๊ฐ„๋„ ๊ฐ™์ด ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค.
  • Dimension ํ…Œ์ด๋ธ”์—์„œ ํŠน์ • entity์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ
  • ์ƒˆ๋กœ์šด Dimension ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑ(History/snapshot ํ…Œ์ด๋ธ”)

2. dbt์˜ ์Šค๋ƒ…์ƒท ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•

โ– ๋จผ์ € snapshots ํด๋”์— ํ™˜๊ฒฝ์„ค์ •์ด ๋จ
โ– snapshots์„ ํ•˜๋ ค๋ฉด ๋ฐ์ดํ„ฐ ์†Œ์Šค๊ฐ€ ์ผ์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผํ•จ
โ— Primary key๊ฐ€ ์กด์žฌํ•ด์•ผํ•จ
โ— ๋ ˆ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ํƒ€์ž„์Šคํƒฌํ”„ ํ•„์š” (updated_at, modified_at ๋“ฑ๋“ฑ)
โ– ๋ณ€๊ฒฝ ๊ฐ์ง€ ๊ธฐ์ค€
โ— Primary key ๊ธฐ์ค€์œผ๋กœ ๋ณ€๊ฒฝ์‹œ๊ฐ„์ด ํ˜„์žฌ DW์— ์žˆ๋Š” ์‹œ๊ฐ„๋ณด๋‹ค ๋ฏธ๋ž˜์ธ ๊ฒฝ์šฐ
โ– Snapshots ํ…Œ์ด๋ธ”์—๋Š” ์ด 4๊ฐœ์˜ ํƒ€์ž„์Šคํƒฌํ”„๊ฐ€ ์กด์žฌ
โ— dbt_scd_id, dbt_updated_at
โ— valid_from, valid_to

3. dbt snapshot ์ ์šฉํ•ด๋ณด๊ธฐ

  • snapshots/scd_user_metadata.sql ํŽธ์ง‘
{% snapshot scd_user_metadata %}
{{
 config(
 target_schema='urface',
 unique_key='user_id',
 strategy='timestamp',
 updated_at='updated_at',
 invalidate_hard_deletes=True
 )
}}
SELECT * FROM {{ source('urface', 'metadata') }}
{% endsnapshot %}

4. dbt snapshot ์‹คํ–‰

  • dbt snapshot ๋ช…๋ น์–ด ์ž…๋ ฅ

5. ์‹ค์Šต

  • raw_data.user_metadata ์—…๋ฐ์ดํŠธ ์‹ค์Šต ๊ฐœ์š”

    • ์†Œ์Šค ํ…Œ์ด๋ธ”์˜ ๊ธฐ์กด ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜์˜ age ๊ทธ๋ฃน์„ ๋ณ€๊ฒฝ

    • ๊ทธ๋ฆฌ๊ณ  dbt snapshot ์‹คํ–‰

    • urface.scd_user_metadata์— ๋ ˆ์ฝ”๋“œ ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

  • ์†Œ์Šค ํ…Œ์ด๋ธ”์˜ ๊ธฐ์กด ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜์˜ age ๊ทธ๋ฃน์„ ๋ณ€๊ฒฝ

SELECT *
FROM raw_data.user_metadata
WHERE user_id = 99;
UPDATE raw_data.user_metadata
SET age = '20-29', updated_at = GETDATE()
WHERE user_id = 99;
  • dbt snapshot ์‹คํ–‰

  • urface.scd_user_metadata์— ๋ ˆ์ฝ”๋“œ ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

SELECT * FROM urface.scd_user_metadata WHERE user_id = 99;

๐Ÿ“Œ DBT Tests

  • ๋ฐ์ดํ„ฐ ํ’ˆ์งˆ์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

    • ๋‚ด์žฅ ์ผ๋ฐ˜ ํ…Œ์ŠคํŠธ (โ€œGenericโ€)

      • unique, not_null, accepted_values, relationships ๋“ฑ์˜ ํ…Œ์ŠคํŠธ ์ง€์›ํ•œ๋‹ค.
      • models ํด๋”
    • ์ปค์Šคํ…€ ํ…Œ์ŠคํŠธ (โ€œSingularโ€)

      • ๊ธฐ๋ณธ์ ์œผ๋กœ SELECT๋กœ ๊ฐ„๋‹จํ•˜๋ฉฐ ๊ฒฐ๊ณผ๊ฐ€ ๋ฆฌํ„ด๋˜๋ฉด โ€œ์‹คํŒจโ€๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.
      • tests ํด๋”

๐Ÿ“Œ DBT Documentation

  • ๊ธฐ๋ณธ ์ฒ ํ•™์€ ๋ฌธ์„œ์™€ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ตœ๋Œ€ํ•œ ๊ฐ€๊น๊ฒŒ ๋ฐฐ์น˜ํ•˜์ž๋Š” ๊ฒƒ์ด๋‹ค.

  • ๋ฌธ์„œํ™” ์ž์ฒด๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค.

    • ๊ธฐ์กด .yml ํŒŒ์ผ์— ๋ฌธ์„œํ™” ์ถ”๊ฐ€ (์„ ํ˜ธ๋˜๋Š” ๋ฐฉ์‹)
    • ๋…๋ฆฝ์ ์ธ markdown ํŒŒ์ผ ์ƒ์„ฑ
  • ์ด๋ฅผ ๊ฒฝ๋Ÿ‰ ์›น์„œ๋ฒ„๋กœ ์„œ๋น™ํ•œ๋‹ค.

    • overview.md๊ฐ€ ๊ธฐ๋ณธ ํ™ˆํŽ˜์ด์ง€๊ฐ€ ๋œ๋‹ค.
    • ์ด๋ฏธ์ง€๋“ฑ์˜ asset ์ถ”๊ฐ€๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

๐Ÿ“Œ DBT Expectations

  • Great Expectations์—์„œ ์˜๊ฐ์„ ๋ฐ›์•„ dbt์šฉ์œผ๋กœ ๋งŒ๋“  dbt ํ™•์žฅํŒ
  • ์„ค์น˜ ํ›„ packages.yml์— ๋“ฑ๋ก
    packages:
  • package: calogica/dbt_expectations
    version: [">=0.7.0", "<0.8.0"]
  • ๋ณดํ†ต์€ ์•ž์„œ dbt ์ œ๊ณต ํ…Œ์ŠคํŠธ๋“ค๊ณผ ๊ฐ™์ด ์‚ฌ์šฉ
    • models/schema.yml

0๊ฐœ์˜ ๋Œ“๊ธ€