[69일차]dbt Models : Output

김준석·2024년 3월 1일

최종 출력 데이터를 만드는 과정을 살펴보자

최종 출력 데이터 과정에서는 Materialization이라는 것을 이해해야 된다.

Materialization이란?

  • 입력 데이터(테이블)들을 연결해서 새로운 데이터(테이블) 생성하는 것(ELT!)
    • 보통 여기서 추가 transformation이나 데이터 클린업 수행
  • 앞단에서 말한 4가지의 내장 materialization이 제공됨
  • 파일이나 프로젝트 레벨에서 가능
  • 역시 dbt run을 기타 파라미터를 가지고 실행

4가지의 Materialization 종류

  • View
    • 데이터를 자주 사용하지 않는 경우
  • Table
    • 데이터를 반복해서 자주 사용하는 경우
  • Incremental (Table Appends)
    • Fact 테이블
    • 과거 레코드를 수정할 필요가 없는 경우
  • Ephemeral (CTE)
    • 한 SELECT에서 자주 사용되는 데이터를 모듈화하는데 사용

아웃풋 이전 Core까지 데이터 빌딩 프로세스

Raw Data 에서부터 클린업 부터 필요한 데이터만 추출 및 계산해서 Core 테이블이 출력된다


models 밑에 core 테이블들을 위한 폴더 생성

  • dim 폴더와 fact 폴더 생성
    • dim 밑에 각각 dim_user_variant.sql과 dim_user_metadata.sql 생성
    • fact 밑에 fact_user_event.sql 생성
  • 이 모두를 physical table로 생성

1. models/dim - dim_user_variant.sql

Jinja 템플릿과 ref 태그를 사용해서 dbt 내 다른 테이블들을 액세스

🔎Jinja 템플릿이란?

❖ 파이썬이 제공해주는 템플릿 엔진으로 Flask에서 많이 사용
● Airflow에서도 사용함
❖ 입력 파라미터 기준으로 HTML 페이지(마크업)를 동적으로 생성
❖ 조건문, 루프, 필터등을 제공

2. models/dim - dim_user_metadata.sql

  • 설정에 따라 view/table/CTE 등으로 만들어져서 사용됨
    • materialized라는 키워드로 설정
WITH src_user_metadata AS (
 SELECT * FROM {{ ref('src_user_metadata') }}
)
SELECT
 user_id,
 age,
 gender,
 updated_at
FROM
 src_user_metadata

3. models/fact - fact_user_event.sql

최종 테이블로 Incremental Table로 빌드 (materialized = 'incremental')

on_schema_change='fail’ = 입력 테이블의 스키마가 바뀌었다면 fail로 처리.

만들어진 model의 materialized format 결정

  • 테이블별로 format결정 방법
    • 최종 Core 테이블들은 view가 아닌 table로 빌드
  • 폴더별로 format 결정 방법
    • dbt_project.yml을 편집

마지막으로 dbt run 수행하면 이전 글 처럼 폴더가 생성되어있을 것이다.

dbt compile vs. dbt run

  • dbt compile : SQL 코드까지만 생성하고 실행하지는 않음
  • dbt run : 생성된 코드를 실제 실행함

Model 빌딩: Compile 결과확인

Compile 후 결과를 확인하는 것이 좋다.

경로 : learn_dbt/target/compiled/learn_dbt/models/fact

fact테이블의 경우 Compile된 형태로 코드가 변환된 것을 확인할 수 있을 것이다.

src 테이블들을 CTE로 변환해보기

src 테이블들을 굳이 빌드할 필요가 있나? CTE형태로 봐도 될거 같다면 아래와 같이 코딩

  • dbt_project.yml 편집
models:
 learn_dbt:
 # Config indicated by + and applies to all files under models
 +materialized: view
 dim:
 +materialized: table
 src:
 +materialized: ephemeral #CTE를 사용하겠다는 명령어

이후 View 테이블들은 삭제 처리.

run을 돌리면 각 테이블은 CTE 형태로 임베드되어서 빌드됨.

아웃풋까지의 최종 데이터 빌딩 프로세스

dim_user 테이블

dim_user_variant와 dim_user_metadata를 조인

WITH um AS (
 SELECT * FROM {{ ref("dim_user_metadata") }}
), uv AS (
 SELECT * FROM {{ ref("dim_user_variant") }}
)
SELECT
 uv.user_id,
 uv.variant_id,
 um.age,
 um.gender
FROM uv
LEFT JOIN um ON uv.user_id = um.user_id

analytics_variant_user_daily

dim_user와 fact_user_event를 조인 - analytics 폴더를 models 밑에 생성

WITH u AS(
 SELECT * FROM {{ ref("dim_user") }}
), ue AS (
 SELECT * FROM {{ ref("fact_user_event") }}
)
SELECT
 variant_id,
 ue.user_id,
 datestamp,
 age,
 gender,
 COUNT(DISTINCT item_id) num_of_items, -- 총 impression
 COUNT(DISTINCT CASE WHEN clicked THEN item_id END) num_of_clicks, -- 총 click
 SUM(purchased) num_of_purchases, -- 총 purchase
 SUM(paidamount) revenue -- 총 revenue
FROM ue LEFT JOIN u ON ue.user_id = u.user_id
GROUP by 1, 2, 3, 4, 5

이후 dbt run을 돌리면 된다!

0개의 댓글