Chapter Data Validation dan Schema Validation membangun aturan validasi dengan kode pandas buatan sendiri. Seiring aturan bertambah, tiga masalah muncul: aturan tercecer di banyak fungsi, tidak ada format laporan yang konsisten, dan tidak ada cara menjelaskan aturan kepada pemilik data tanpa membaca kode. Great Expectations (GX) menyatukan semuanya: setiap aturan ditulis sebagai expectation — pernyataan berbahasa hampir manusia seperti “kolom total tidak boleh null” — yang dikumpulkan dalam expectation suite dan dijalankan dengan laporan baku. Chapter ini memasang GX versi 1.x, membangun suite untuk tabel pesanan TokoKita, lalu mengujinya pada data sehat dan data bermasalah.
Model API GX Core 1.x #
GX versi 1.x mengatur akses data lewat rantai objek yang eksplisit. Konteks menjadi akar, data source menjelaskan dari mana data dibaca, asset menyatakan unit data (satu tabel), dan batch definition menentukan potongan data yang divalidasi:
DataContext -> DataSource(pandas) -> DataAsset(pesanan) -> BatchDefinitionPola ini membuat sumber data dan aturan validasi terpisah: satu batch definition bisa divalidasi dengan suite apa pun, dan satu suite bisa dipakai pada batch dari hari yang berbeda. Untuk contoh ini kita memakai pandas data source, sehingga validasi berjalan pada DataFrame di memori tanpa perlu koneksi database. Seluruh contoh pada chapter ini dijalankan nyata dengan GX 1.24 di lingkungan penulisan materi.
Expectation Suite untuk Tabel Pesanan #
Instalasi cukup satu perintah pip install great-expectations. Skrip berikut membangun suite berisi empat expectation — id_pesanan wajib ada dan unik, status harus salah satu dari tiga nilai resmi, total harus berada di rentang nilai yang wajar — lalu memvalidasinya pada dua DataFrame: satu sehat, satu berisi tiga jenis pelanggaran:
"""Validasi DataFrame pandas dengan GX Core 1.x fluent API."""
import great_expectations as gx
import great_expectations.expectations as gxe
import pandas as pd
df_baik = pd.DataFrame({
"id_pesanan": [101, 102, 103, 104, 105, 106],
"status": ["lunas", "belum", "lunas", "dibatalkan", "lunas", "belum"],
"total": [250_000.0, 90_000.0, 12_500.0, 175_000.0, 60_000.0, 8_500.0],
})
df_buruk = pd.DataFrame({
"id_pesanan": [201, 202, 203, 203, 205, 206],
"status": ["lunas", "PAID", "belum", "lunas", "belum", "belum"],
"total": [310_000.0, 1_250_000.0, 45_000.0, 45_000.0, 7_500.0, 8_000.0],
})
context = gx.get_context()
data_source = context.data_sources.add_pandas("tokokita")
asset = data_source.add_dataframe_asset("pesanan")
batch_definition = asset.add_batch_definition_whole_dataframe("batch_harian")
suite = gx.ExpectationSuite(name="suite_pesanan")
suite.add_expectation(gxe.ExpectColumnValuesToNotBeNull(column="id_pesanan"))
suite.add_expectation(gxe.ExpectColumnValuesToBeUnique(column="id_pesanan"))
suite.add_expectation(
gxe.ExpectColumnValuesToBeInSet(
column="status", value_set=["lunas", "belum", "dibatalkan"]
)
)
suite.add_expectation(
gxe.ExpectColumnValuesToBeBetween(
column="total", min_value=0, max_value=1_000_000
)
)
def jalankan_validasi(df, label):
batch = batch_definition.get_batch(batch_parameters={"dataframe": df})
hasil = batch.validate(suite)
print(f"== Validasi {label} ==")
print(f"success : {hasil.success}")
print(f"statistics: {hasil.statistics}")
for r in hasil.results:
tipe = r.expectation_config.type
if r.success:
print(f" LULUS {tipe}")
else:
tak_terduga = r.result.get("partial_unexpected_list")
print(f" GAGAL {tipe} -> nilai bermasalah: {tak_terduga}")
print()
jalankan_validasi(df_baik, "df_baik")
jalankan_validasi(df_buruk, "df_buruk")Output yang Dihasilkan:
== Validasi df_baik ==
success : True
statistics: {'evaluated_expectations': 4, 'successful_expectations': 4, 'unsuccessful_expectations': 0, 'success_percent': 100.0}
LULUS expect_column_values_to_not_be_null
LULUS expect_column_values_to_be_unique
LULUS expect_column_values_to_be_in_set
LULUS expect_column_values_to_be_between
== Validasi df_buruk ==
success : False
statistics: {'evaluated_expectations': 4, 'successful_expectations': 1, 'unsuccessful_expectations': 3, 'success_percent': 25.0}
LULUS expect_column_values_to_not_be_null
GAGAL expect_column_values_to_be_unique -> nilai bermasalah: [203, 203]
GAGAL expect_column_values_to_be_in_set -> nilai bermasalah: ['PAID']
GAGAL expect_column_values_to_be_between -> nilai bermasalah: [1250000.0]GX menulis progress bar ke stderr saat menghitung metrik; output di atas adalah stdout murni dari eksekusi nyata dengan stderr dialihkan. Mari kita telaah bagian-bagian kuncinya:
- Baris 19-22 (rantai objek):
add_pandasmembuat data source pandas,add_dataframe_assetmendaftarkan asset, danadd_batch_definition_whole_dataframemenyatakan satu batch sama dengan seluruh DataFrame — varian paling sederhana; batch bertanggal memakai pola lain. - Baris 24-36 (
suite): empat expectation ditambahkan satu per satu; setiap kelas expectation menerima parameter kolom plus batasannya, misalnyavalue_setuntuk daftar nilai sah. batch_parameters={"dataframe": df}: batch hanya terikat ke DataFrame konkret saatget_batchdipanggil, sehingga satu batch definition dipakai ulang untukdf_baikdandf_buruk.hasil.statistics: ringkasan hitungan (evaluated,successful,unsuccessful,success_percent) yang pas disimpan sebagai metric di sistem monitoring.partial_unexpected_list: daftar nilai pelanggar — duplikasi203, nilaiPAIDyang bukan bagian kosakata, dan1250000.0di luar rentang. Awalan partial berarti daftar dipotong maksimal 20 nilai pada format hasil BASIC.
Kapan Memakai GX #
Kekuatan GX mulai terasa ketika validasi menjadi bagian operasi harian. Expectation suite berfungsi sebagai dokumentasi hidup: pemilik data bisa membaca “kolom status harus di antara lunas, belum, dibatalkan” tanpa membaca kode, dan setiap perubahan aturan tercatat di version control bersama kode pipeline.
Untuk jadwal berulang, GX menyediakan ValidationDefinition (pasangan suite + batch definition) dan Checkpoint (jalankan beberapa validasi lalu kirim hasilnya ke action seperti notifikasi Slack atau pembaruan Data Docs — laporan HTML yang bisa dibagikan). Batas praktisnya: GX berjalan sebagai proses Python tersendiri dan framework-nya cukup tebal, sehingga untuk validasi ringkas di dalam fungsi pipeline, alat yang lebih tipis sering lebih pas.
Suite GX menyimpan aturan; eksekusinya tetap membutuhkan proses validasi tersendiri. Bila kebutuhan kita adalah validasi langsung di dalam fungsi transformasi — schema check di pintu masuk, galat yang bisa ditangkap sebagai exception biasa — ada pustaka yang jauh lebih ringan untuk itu: Pandera, materi chapter berikutnya.