TL;DR
dbt adalah tool yang bikin kamu ngerjain transformasi data pakai file SQL biasa, lalu dijalankan berurutan sesuai ketergantungan antarmodel. Tujuh konsep yang harus kamu pahami sebelum mulai: model, fungsi ref, materialization, test, source, dokumentasi, dan lineage. Yang paling ngubah cara kerja itu fungsi ref, soalnya dari situ dbt tau urutan jalannya query tanpa kamu atur manual.
dbt adalah tool yang bikin kamu ngerjain transformasi data pakai file SQL biasa, lalu dijalankan berurutan sesuai ketergantungan antarquery.
Nama panjangnya data build tool. Yang dikerjain cuma satu huruf dari ETL: huruf T, transform. Narik dan masukin data tetap urusan tool lain.
Kenapa analis perlu tau ini? Karena begitu jumlah query rekap kamu lewat 20 file, ngatur urutan jalannya manual itu udah nggak masuk akal. Satu tabel sumber berubah nama, dan kamu harus nyari file mana aja yang kena.
Tujuh konsep di bawah ini yang perlu kamu pahami sebelum buka dokumentasinya.
Model adalah satu file .sql yang isinya satu perintah SELECT. Nama filenya jadi nama tabel atau view hasilnya.
Nggak ada CREATE TABLE, nggak ada DROP. Kamu nulis SELECT-nya doang, dbt yang ngurus sisanya.
-- models/staging/stg_transaksi.sql
SELECT
id AS transaksi_id,
tgl_trx AS tanggal,
kode_produk AS produk_id,
jumlah AS qty,
harga AS harga_satuan,
LOWER(status) AS status
FROM {{ source('pos', 'transaksi_mentah') }}
Ini yang bikin dbt gampang diterima analis. Isi filenya query yang kamu udah biasa tulis.
Ini konsep paling penting di seluruh dbt.
Waktu satu model butuh hasil model lain, kamu nggak nulis nama tabelnya langsung. Kamu pakai ref.
SELECT * FROM {{ ref('stg_transaksi') }}
Dari situ dbt tau dua hal sekaligus. Pertama, nama tabel sebenarnya di database, yang bisa beda antara lingkungan pengembangan dan produksi. Kedua, urutan jalannya: stg_transaksi harus selesai dulu sebelum model ini dijalankan.
Kamu nggak pernah nulis urutan eksekusi secara manual. dbt nyusunnya sendiri dari semua ref yang ada di proyek.
Efek sampingnya enak: waktu kamu ganti nama satu model, semua yang manggil dia bakal error waktu dbt run. Ketahuan di awal, bukan pas dashboard udah kosong.
Tabel mentah dari sistem lain didaftarkan dulu sebagai source di file YAML, baru dipanggil pakai fungsi source.
sources:
- name: pos
schema: raw_pos
tables:
- name: transaksi_mentah
- name: produk_mentah
Gunanya bukan cuma rapi-rapi. Dari daftar ini kamu bisa pasang pengecekan kesegaran data: kalau tabel transaksi_mentah nggak nambah baris lebih dari 12 jam, dbt kasih peringatan.
Banyak masalah data quality ketahuan di sini, sebelum sempat nyampe ke dashboard.
Satu model bisa dijadiin view, table, incremental, atau ephemeral. Kamu tinggal atur di konfigurasi.
| Jenis | Cara kerja | Kapan dipakai |
|---|---|---|
| view | Cuma nyimpen definisi query | Model staging yang ringan |
| table | Bikin ulang tabel penuh tiap kali jalan | Model akhir yang dipakai dashboard |
| incremental | Cuma nambahin baris baru | Tabel besar yang datanya nambah tiap hari |
| ephemeral | Nggak dibikin di database, disisipkan sebagai CTE | Potongan logika yang dipakai ulang |
Pilihan default-nya view. Ganti ke table waktu query dashboard mulai lambat.
Incremental itu yang paling sering bikin pusing pemula. Kamu harus nentuin kunci unik dan aturan mana baris yang dianggap baru. Tunda dulu sampai kamu beneran butuh.
Test di dbt itu query yang nyari baris bermasalah. Kalau ada yang ketemu, test-nya gagal.
Empat test bawaan yang paling sering dipakai:
unique: kolom ini nggak boleh ada nilai kembar.not_null: kolom ini nggak boleh kosong.accepted_values: isinya harus salah satu dari daftar yang kamu tentukan.relationships: tiap nilai di kolom ini harus ada di tabel lain.models:
- name: stg_transaksi
columns:
- name: transaksi_id
tests:
- unique
- not_null
- name: status
tests:
- accepted_values:
values: ['selesai', 'batal', 'pending']
Test relationships itu penyelamat. Dia nangkep transaksi dengan kode produk yang nggak ada di master produk, kasus yang bikin omzet di dashboard lebih kecil dari kenyataan tanpa ada yang sadar.
Deskripsi model dan kolom ditulis di file YAML yang sama dengan test-nya.
models:
- name: penjualan_harian
description: "Rekap omzet per tanggal per kategori, cuma transaksi berstatus selesai."
columns:
- name: omzet
description: "qty dikali harga_satuan, sebelum diskon."
Kalimat "sebelum diskon" itu yang bikin dokumentasi berguna. Definisi metric yang nempel di kolomnya bikin orang nggak perlu nebak.
Jalankan dbt docs generate lalu dbt docs serve, dan semua deskripsinya jadi situs yang bisa dibuka tim.
Karena semua model saling manggil pakai ref, dbt bisa gambar grafik ketergantungannya sendiri.
Gunanya kelihatan waktu ada yang nanya "kalau kolom ini aku hapus, apa yang rusak?". Buka grafiknya, lihat cabangnya.
Ini juga yang bikin kamu bisa jalanin sebagian model doang:
dbt run --select penjualan_harian+
Tanda plus di belakang artinya model itu plus semua yang bergantung padanya. Taruh plus di depan buat semua yang jadi bahan bakunya.
Ini model akhir yang gabungin transaksi dan produk, lalu ngerekap per tanggal per kategori.
-- models/marts/penjualan_harian.sql
WITH transaksi AS (
SELECT * FROM {{ ref('stg_transaksi') }}
),
produk AS (
SELECT * FROM {{ ref('stg_produk') }}
)
SELECT
t.tanggal,
p.kategori,
COUNT(DISTINCT t.transaksi_id) AS jumlah_transaksi,
SUM(t.qty * t.harga_satuan) AS omzet
FROM transaksi t
JOIN produk p ON t.produk_id = p.produk_id
WHERE t.status = 'selesai'
GROUP BY t.tanggal, p.kategori
Sebelum dipindah ke dbt, tiga query rekap toko_berkah dijalankan manual tiap pagi lewat editor SQL. Urutannya diinget di kepala, dan sesekali kebalik.
Waktu susunannya dipindah ke dbt dengan 9 model dan 14 test, ada satu temuan yang langsung muncul di hari pertama: 37 baris transaksi punya kode produk yang nggak ada di master produk. Nilainya Rp 1.240.000, sekitar 0,86 persen dari omzet bulan itu.
Angka itu selama berbulan-bulan hilang begitu aja dari laporan, soalnya JOIN biasa diam-diam ngebuang baris yang nggak ketemu pasangannya. Test relationships yang nangkep.
Detail konfigurasi tiap konsep di atas ada di dokumentasi resmi dbt.
Nulis nama tabel langsung, bukan pakai ref. Query-nya tetap jalan, tapi dbt jadi nggak tau urutannya. Suatu hari model dijalankan sebelum bahan bakunya siap, dan hasilnya kosong tanpa error.
Bikin satu model raksasa. Query 300 baris dengan 8 CTE itu susah diuji dan susah diperbaiki. Pecah jadi staging, perantara, dan mart.
Semua model dijadiin table. Biaya komputasi gudang data naik tanpa manfaat. Model staging yang cuma ganti nama kolom cukup jadi view.
Nggak pasang test dari awal. Nambahin test setelah 40 model itu kerjaan besar yang nggak pernah kelar. Pasang unique dan not_null di kunci utama tiap kali bikin model baru.
Nyampur logika bisnis di dashboard. Kalau definisi omzet ditulis ulang di Looker Studio, dbt kamu nggak ada gunanya. Semua perhitungan turun ke model, dashboard cuma nampilin.
Tambahan. Kamu tetap nulis SELECT biasa. dbt cuma ngatur file-nya, urutan jalannya, dan hasilnya disimpan sebagai apa. Yang baru kamu pelajari cuma beberapa fungsi kayak ref dan source, plus struktur folder. Kalau SQL kamu udah lancar, satu minggu cukup buat ngerti alurnya. Bagian yang lebih lama itu belajar nyusun model biar rapi.
Nggak perlu. Isi proyek dbt itu file SQL dan file YAML buat konfigurasi. Python cuma muncul kalau kamu mau bikin model Python di gudang data yang mendukung, dan itu jarang dipakai analis pemula. Yang lebih berguna dipelajari duluan justru Git, soalnya alur kerja dbt ngandelin versi file.
dbt jalan lewat adapter, jadi dukungannya tergantung adapter yang tersedia. Yang paling umum dipakai: BigQuery, Snowflake, Redshift, Databricks, PostgreSQL, dan DuckDB. Buat latihan di laptop, DuckDB pilihan paling gampang soalnya nggak butuh server. Cek daftar adapter resmi sebelum kamu ngerencanain proyek, terutama kalau database kamu di luar yang umum.
View nggak nyimpen data, cuma nyimpen definisi query, jadi cepat dibuat tapi lambat dibaca kalau datanya besar. Table nyimpen hasilnya beneran, jadi lambat dibuat tapi cepat dibaca. Patokan gampangnya: pakai view buat model staging yang isinya cuma ganti nama kolom, pakai table buat model akhir yang dipakai dashboard.
dbt punya versi command line yang open source dan gratis dipakai. Versi berbayarnya nyediain layanan terkelola dengan penjadwal, antarmuka web, dan fitur kolaborasi tim. Buat belajar dan buat tim kecil, versi command line udah cukup. Biaya yang beneran perlu kamu hitung itu biaya gudang datanya, bukan dbt-nya.
Dua konsep yang paling ngubah cara kerja:
ref bikin urutan jalannya query diurus otomatis, dan bikin perubahan nama ketahuan sebelum masuk produksi.Kalau kamu mau nyoba, mulai dari proyek kecil: dua model staging dan satu model rekap. Pakai DuckDB biar nggak usah nyiapin server.
Yang perlu kuat duluan tetap SQL-nya. CTE, JOIN, dan window function itu bahan sehari-hari di dbt. Latihannya bisa kamu kerjain di NgulikSQL.
Lanjut baca: query SQL buat cek kualitas data buat ngerti logika di balik test dbt, dan SQL SCD Type 2 kalau kamu mau nyimpen riwayat perubahan data dimensi.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Kolom datetime nyimpen tanggal, jam, hari, semuanya nempel jadi satu. Accessor .dt di pandas ngeluarin tiap bagian jadi kolom sendiri buat dianalisa.
Nama toko ketik campur huruf besar-kecil, spasi nyasar di ujung, atau kode produk nempel jadi satu. Accessor .str di pandas ngerapiin semua itu tanpa loop.
Model machine learning cuma ngerti angka, bukan teks kayak merah atau biru. get_dummies ngubah kolom kategori jadi kolom 0/1 dalam satu baris kode.