Traffine I/O

Bahasa Indonesia

2022-12-30

model dbt

Apa itu model dalam dbt

Di dbt, model adalah pernyataan SELECT SQL. Model didefinisikan dalam file .sql (.py) dan disimpan secara default di direktori models.

Model SQL

Setiap file .sql terdiri dari satu model dengan satu pernyataan SELECT. Juga, nama file digunakan sebagai nama model. Ketika anda menjalankan perintah dbt run, dbt akan membungkus model dalam pernyataan CREATE VIEW as atau CREATE TABLE as dan mengeksekusi SQL.

Sebagai contoh, pertimbangkan model customers berikut ini.

models/customers.sql
with customer_orders as (
    select
        customer_id,
        min(order_date) as first_order_date,
        max(order_date) as most_recent_order_date,
        count(order_id) as number_of_orders
    from jaffle_shop.orders
    group by 1
)
select
    customers.customer_id,
    customers.first_name,
    customers.last_name,
    customer_orders.first_order_date,
    customer_orders.most_recent_order_date,
    coalesce(customer_orders.number_of_orders, 0) as number_of_orders
from jaffle_shop.customers
left join customer_orders using (customer_id)

Ketika anda menjalankan perintah dbt run, dbt akan mengeksekusi SQL berikut ini untuk membuat tabel view bernama customers. Tabel view akan dibuat dalam skema (dataset) yang ditentukan. Dalam contoh berikut, skema (dataset) adalah dbt_alice. Juga, nama tabel view, customers, berasal dari nama file customers.sql.

create view dbt_alice.customers as (
    with customer_orders as (
        select
            customer_id,
            min(order_date) as first_order_date,
            max(order_date) as most_recent_order_date,
            count(order_id) as number_of_orders

        from jaffle_shop.orders

        group by 1
    )

    select
        customers.customer_id,
        customers.first_name,
        customers.last_name,
        customer_orders.first_order_date,
        customer_orders.most_recent_order_date,
        coalesce(customer_orders.number_of_orders, 0) as number_of_orders

    from jaffle_shop.customers

    left join customer_orders using (customer_id)
)

dbt akan membungkus model dengan pernyataan CREATE TABLE as.

Mengkonfigurasi model

Model dapat dikonfigurasi di dbt_project.yml atau di blok config dari setiap model. Sebagai contoh, jika Anda ingin mengkonfigurasi materialisasi dan skema,

dbt_project.yml
name: jaffle_shop
config-version: 2
...

models:
  jaffle_shop: # this matches the `name:`` config
    +materialized: view # this applies to all models in the current project
    marts:
      +materialized: table # this applies to all models in the `marts/` directory
      marketing:
        +schema: marketing # this applies to all models in the `marts/marketing/`` directory
models/customer.sql
{{ config(
    materialized="view",
    schema="marketing"
)}}

with customer_orders as ...

Pengaturan diterapkan secara hirarkis. Konfigurasi yang diterapkan pada subdirektori akan mengesampingkan konfigurasi umum, contohnya, jika sebuah model dikonfigurasi di dbt_project.yml dan config, maka konfigurasi di config akan diutamakan.

Model Python

Model Python memungkinkan Anda untuk menggunakan alat yang tersedia di ekosistem Python, termasuk paket ilmu data dan statistik yang canggih.

Setiap model Python disimpan dalam file .py di folder models/. Sebuah fungsi yang disebut model() didefinisikan dan mengambil dua parameter berikut.

  • dbt
    Sebuah kelas khusus untuk setiap model yang dikompilasi oleh dbt Core yang dapat merepresentasikan ketergantungan model.
  • session
    Kelas yang mewakili koneksi dari platform data ke backend Python. session diperlukan untuk membaca tabel sebagai DataFrames dan menulis DataFrames kembali ke tabel.

Fungsi model() ` harus mengembalikan satu DataFrame.

models/my_python_model.py
import ...

def model(dbt, session):
    final_df = ...  # stuff you can't write in SQL!
    return final_df

Selain mendefinisikan fungsi model, Anda bisa mengimpor fungsi lain atau mendefinisikan fungsi Anda sendiri.

models/my_python_model.py
def add_one(x):
    return x + 1

def model(dbt, session):
    dbt.config(materialized="table")
    temps_df = dbt.ref("temperatures")

    # warm things up just a little
    df = temps_df.withColumn("degree_plus_one", add_one(temps_df["degree"]))
    return df
models/my_python_model.py
import holidays

def is_holiday(date_col):
    # Chez Jaffle
    french_holidays = holidays.France()
    is_holiday = (date_col in french_holidays)
    return is_holiday

def model(dbt, session):
    dbt.config(
        materialized = "table",
        packages = ["holidays"]
    )

    orders_df = dbt.ref("stg_orders")

    df = orders_df.to_pandas()

    # apply our function
    # (columns need to be in uppercase on Snowpark)
    df["IS_HOLIDAY"] = df["ORDER_DATE"].apply(is_holiday)

    # return final dataset (Pandas DataFrame)
    return df

Mengkonfigurasi model

Model dapat dikonfigurasi dalam tiga pola berikut:

  • Konfigurasikan mereka di dbt_project.yml.
  • Konfigurasi dengan membuat file .yml di direktori models/.
  • Konfigurasi dengan memanggil metode dbt.config() di setiap model .py.

Jika Anda membuat file .yml di direktori models/ dan mengkonfigurasinya, maka akan terlihat seperti ini

models/config.yml
version: 2

models:
  - name: my_python_model
    config:
      materialized: table
      target_name: "{{ target.name }}"
      specific_var: "{{ var('SPECIFIC_VAR') }}"
      specific_env_var: "{{ env_var('SPECIFIC_ENV_VAR') }}"
models/my_python_model.py
def model(dbt, session):
    target_name = dbt.config.get("target_name")
    specific_var = dbt.config.get("specific_var")
    specific_env_var = dbt.config.get("specific_env_var")

    orders_df = dbt.ref("fct_orders")

    # limit data in dev
    if target_name == "dev":
        orders_df = orders_df.limit(500)

Jika Anda memanggil metode dbt.config() di .py untuk mengkonfigurasinya, maka akan terlihat seperti ini

models/my_python_model.py
def model(dbt, session):

    # setting configuration
    dbt.config(materialized="table")

Keterbatasan

Model Python memiliki kekurangan berikut ini:

  • Waktu dan biaya
    Model Python lebih lambat untuk dieksekusi daripada model SQL, dan resource cloud untuk menjalankannya lebih mahal; Python membutuhkan komputasi tujuan yang lebih umum untuk dijalankan, dan mungkin memerlukan layanan atau arsitektur yang berbeda dari model SQL.
  • Perbedaan sintaks
    dbt telah bekerja untuk mengabstraksikan perbedaan antara dialek SQL dalam data warehouse yang khas melalui paket-paket seperti pola dispatch dan dbt_utils. python memiliki lebih banyak dialek daripada SQL. jika ada 5 cara untuk melakukan sesuatu di SQL, ada 500 cara untuk melakukannya di Python. Jika ada 5 cara untuk melakukan sesuatu di SQL, ada 500 cara untuk menuliskannya di Python, dengan berbagai tingkat kinerja dan kepatuhan standar.

Jika ada konversi yang dapat ditulis dengan sama baiknya dalam SQL dan Python, SQL kemungkinan adalah pilihan yang lebih baik; jika ada konversi yang tidak dapat ditulis dalam SQL, atau jika Anda dapat menyimpan 1000 baris Jinja-SQL yang tidak dapat dibaca dengan 10 baris Python yang elegan dan beranotasi, maka Python kemungkinan adalah pilihan yang lebih baik. Python tampaknya menjadi pilihan yang lebih baik jika Anda dapat menyimpan 1000 baris Jinja-SQL yang sulit dibaca.

Referensi

https://docs.getdbt.com/docs/build/models
https://docs.getdbt.com/docs/build/sql-models
https://docs.getdbt.com/docs/build/python-models

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!