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.
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,
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
{{ 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.
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.
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
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 direktorimodels/
. - 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
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') }}"
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
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 dandbt_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