Firebolt 설정

Firebolt 설정

dbt-firebolt 어댑터에서 fact/dimension 테이블, aggregating index, 외부 테이블, incremental 전략 등을 구성하는 방법을 다루는 페이지예요. Firebolt 특유의 table_type, primary_index, indexes 같은 설정을 정확히 이해하는 게 중요해요.

출처: 문서

본문

quote_columns 설정하기

경고를 피하려면 dbt_project.yml에서 quote_columns 값을 명시적으로 설정해야 해요. 자세한 내용은 quote_columns 문서를 참고하세요.

seeds:
  +quote_columns: false  #or `true` if you have CSV column headers with spaces

Fact 테이블 모델 구성

dbt 모델은 Firebolt fact 테이블로 생성할 수 있고, 다음 문법으로 구성해요.

Project YAML 파일

dbt_project.yml

models:
  <resource-path>:
    +materialized: table
    +table_type: fact
    +primary_index: [ <column-name>, ... ]
    +indexes:
      - index_type: aggregating
        key_columns: [ <column-name>, ... ]
        aggregation: [ <agg-sql>, ... ]
      ...

Properties YAML 파일

models/properties.yml

models:
  - name: <model-name>
    config:
      materialized: table
      table_type: fact
      primary_index: [ <column-name>, ... ]
      indexes:
        - index_type: aggregating
          key_columns: [ <column-name>, ... ]
          aggregation: [ <agg-sql>, ... ]
        ...

SQL 파일 config

models/<model_name>.sql

{{ config(
    materialized = "table"
    table_type = "fact"
    primary_index = [ "<column-name>", ... ],
    indexes = [
      {
        "index_type": "aggregating"
        "key_columns": [ "<column-name>", ... ],
        "aggregation": [ "<agg-sql>", ... ],
      },
      ...
    ]
) }}
Fact 테이블 구성
구성 설명
materialized 모델이 Firebolt에 어떻게 materialize되는지를 나타내요. fact 테이블을 만들려면 table이어야 해요.
table_type materialize된 테이블이 fact인지 dimension인지를 나타내요.
primary_index 모델의 컬럼 이름 목록을 사용해 fact 테이블의 기본 인덱스를 설정해요. fact 테이블에 필수예요.
indexes fact 테이블에 만들 aggregating index 목록이에요.
index_type 인덱스가 aggregating index임을 지정해요. aggregating으로 설정해야 해요.
key_columns 모델의 컬럼 이름 목록을 사용해 aggregating index의 그룹핑을 설정해요.
aggregation SQL 집계 표현식 목록을 사용해 aggregating index의 집계를 설정해요.
Aggregating index를 가진 fact 테이블 예시
{{ config(
    materialized = "table",
    table_type = "fact",
    primary_index = "id",
    indexes = [
      {
        "index_type": "aggregating",
        "key_columns": "order_id",
        "aggregation": ["COUNT(DISTINCT status)", "AVG(customer_id)"]
      }
    ]
) }}

Dimension 테이블 모델 구성

dbt 모델은 Firebolt dimension 테이블로 materialize할 수 있고, 다음 문법으로 구성해요.

Project YAML 파일

dbt_project.yml

models:
  <resource-path>:
    +materialized: table
    +table_type: dimension
    ...

Properties YAML 파일

models/properties.yml

models:
  - name: <model-name>
    config:
      materialized: table
      table_type: dimension
    ...

SQL 파일 config

models/<model_name>.sql

{{ config(
    materialized = "table",
    table_type = "dimension",
    ...
) }}

Dimension 테이블은 aggregation index를 지원하지 않아요.

Dimension 테이블 구성

구성 설명
materialized 모델이 Firebolt에 어떻게 materialize되는지를 나타내요. dimension 테이블을 만들려면 table이어야 해요.
table_type materialize된 테이블이 fact인지 dimension인지를 나타내요.

Aggregating index 이름 지어지는 방식

dbt-firebolt에서는 aggregating index의 이름을 직접 지정하지 않아요. 프로그래밍 방식으로 이름이 지어져요. dbt는 다음 규칙으로 인덱스 이름을 생성해요:

<table-name>__<key-column>__<index-type>_<unix-timestamp-at-execution>

예를 들어 join index는 my_users__id__join_1633504263, aggregating index는 my_orders__order_date__aggregating_1633504263처럼 이름이 붙을 수 있어요.

외부 테이블을 통한 수집 관리 (Managing ingestion via external tables)

dbt-firebolt는 dbt의 external tables 기능을 지원해요. 이를 통해 dbt가 S3에서 Firebolt로의 테이블 수집 프로세스를 관리할 수 있어요. 선택 기능이지만 사용 사례에 따라 매우 편리할 수 있어요.

IAM을 제대로 구성하는 방법을 포함한 외부 테이블 사용에 대한 자세한 내용은 Firebolt documentation에서 확인할 수 있어요.

외부 테이블 패키지 설치

Firebolt에서 dbt-external-tables를 설치하고 사용하려면:

  1. 이 패키지를 packages.yml에 추가하세요:

    packages:
      - package: dbt-labs/dbt_external_tables
        version: <version>
    
  2. dbt_project.yml에 이 필드들을 추가하세요:

    dispatch:
      - macro_namespace: dbt_external_tables
        search_order: ['dbt', 'dbt_external_tables']
    
  3. dbt deps를 호출해 packages.yml 의존성을 가져오세요.

외부 테이블 사용하기

외부 테이블을 사용하려면 dbt_project.yml 파일에서 테이블을 external로 정의해야 해요. 모든 외부 테이블은 url, type, object_pattern 필드를 포함해야 해요. Firebolt 외부 테이블 명세는 dbt 문서에 명시된 것보다 더 적은 필드만 필요하다는 점에 주의하세요.

컬럼을 지정하는 것 외에도 외부 테이블은 파티션을 지정할 수 있어요. 파티션은 컬럼이 아니며 컬럼과 같은 이름을 가질 수 없어요. YAML 파싱 오류를 피하려면 문자열 리터럴(url, object_pattern 값 등)을 단일 인용부호로 감싸는 것을 기억하세요.

외부 테이블의 dbt_project.yml 문법

sources:
  - name: firebolt_external
    schema: "{{ target.schema }}"
    loader: S3

    tables:
      - name: <table-name>
        external:
          url: 's3://<bucket_name>/'
          object_pattern: '<regex>'
          type: '<type>'
          credentials:
            aws_key_id: <key-id>
            aws_secret_key: <key-secret>
          object_pattern: '<regex>'
          compression: '<compression-type>'
          partitions:
            - name: <partition-name>
              data_type: <partition-type>
              regex: '<partition-definition-regex>'
          columns:
            - name: <column-name>
              data_type: <type>

aws_key_idaws_secret_key는 Firebolt가 S3 버킷에 접근할 수 있게 하는 자격 증명이에요. 이 가이드를 따라 설정하는 방법을 알아보세요. 버킷이 공개(public)라면 이 파라미터는 필요 없어요.

외부 테이블 실행하기

stage_external_sources 매크로는 dbt-external-tables 패키지에서 상속되며, 이 패키지를 사용할 때의 주요 진입점이에요. 표준 모드와 "full refresh" 두 가지 작동 모드가 있어요.

# iterate through all source nodes, create if missing, refresh metadata
$ dbt run-operation stage_external_sources

# iterate through all source nodes, create or replace (no refresh command is required as data is fetched live from remote)
$ dbt run-operation stage_external_sources --vars "ext_full_refresh: true"

Incremental 모델

incremental_strategy 구성은 dbt가 incremental 모델을 어떻게 빌드할지 제어해요. Firebolt는 현재 append, insert_overwrite, delete+insert 구성을 지원해요. incremental_strategydbt_project.yml 또는 모델 파일의 config() 블록 안에서 지정할 수 있어요. append 구성이 기본이며, 지정하는 것은 선택 사항이에요.

append 전략은 모델 정의에 따라 모든 새 데이터로 INSERT INTO 문을 실행해요. 이 전략은 기존 행을 업데이트하거나 삭제하지 않으므로, 데이터를 가장 최근 레코드만으로 필터링하지 않으면 중복 레코드가 삽입될 가능성이 커요.

소스 코드 예시:

{{ config(
   materialized = 'incremental',
   incremental_strategy='append'
) }}

/* All rows returned by this query will be appended to the existing model */


select * from {{ ref('raw_orders') }}
{% if is_incremental() %}
   where order_date > (select max(order_date) from {{ this }})
{% endif %}

실행 코드 예시:

CREATE DIMENSION TABLE IF NOT EXISTS orders__dbt_tmp AS
SELECT * FROM raw_orders
WHERE order_date > (SELECT MAX(order_date) FROM orders);

INSERT INTO orders VALUES ([columns])
SELECT ([columns])
FROM orders__dbt_tmp;

Seeds 동작 (Seeds behavior)

dbt seed 명령을 실행할 때는 TRUNCATE 대신 DROP CASCADE 연산을 수행해요.

연습 (Practice)

인덱스와 외부 테이블을 어떻게 설정하거나 복제하는지 보려면, 수정된 버전의 jaffle_shop인 jaffle_shop_firebolt를 살펴보고 README.md에 나열된 명령을 실행해 보세요.

더 알아보기 (Learn more)