Proyek pipeline yang gagal hampir selalu gagal sejak awal: bukan karena kodenya salah, tetapi karena kebutuhannya tidak pernah ditulis. Pada bagian ini kita memperlakukan pekerjaan data engineer sebagaimana seharusnya: memahami data sumber, menetapkan kriteria berhasil yang terukur, dan menetapkan batas sebelum menulis kode. Pembahasan kita berpindah dari konsep Merancang Data Pipeline dan Ingestion dari File yang telah dipelajari, menjadi satu keputusan konkret untuk TokoKita.
Skenario: Ekspor CSV TokoKita #
Sistem order TokoKita adalah aplikasi warisan yang tidak punya API. Satu-satunya cara mengambil datanya adalah ekspor CSV bulanan ke folder bersama. Dua berkas yang kita terima berisi kolom berikut:
order_id, tanggal, pelanggan, email, produk, kategori, jumlah, harga, statusPembacaannya di pipeline memakai modul csv bawaan Python; format CSV sendiri sudah dibahas pada chapter CSV.
Tim analitik tidak bisa memakai berkas tersebut langsung karena tiga hal. Pertama, jumlah baris tidak dapat dipercaya: pesanan yang sama bisa muncul dua kali. Kedua, tipe data tidak konsisten: angka kadang ditulis dengan pemisah ribuan, status kadang huruf kecil kadang huruf besar. Ketiga, sebagian baris berisi nilai yang tidak masuk akal untuk dibaca analitik.
Audit Data Mentah #
Kita membaca kedua berkas baris demi baris dan mengelompokkan temuan. Hasilnya menjadi daftar masalah yang harus dijawab pipeline:
| Jenis kotoran | Contoh nyata di berkas | Dampak jika dibiarkan |
|---|---|---|
| Duplikat persis | ORD-2024-0004 muncul 2 kali di berkas Juni | Omzet terhitung ganda |
| Duplikat lintas berkas | 3 pesanan Juni diekspor ulang di berkas Juli | Baris tabel membengkak |
| Konflik kunci | ORD-2024-0046 isi berbeda antar berkas | Analitik tidak tahu versi mana yang benar |
| Nilai kosong | email kosong, harga kosong, tanggal kosong | Kolom wajib menjadi tidak dapat dipakai |
| Nilai mustahil | jumlah -2, tanggal 2024-06-31 | Agregasi menghasilkan angka negatif |
| Format bervariasi | 210.000 vs 210000, selesai vs SELESAI | Filter dan GROUP BY terpecah |
| Pola tidak sesuai | ORD-2024-631, budi(at)example.com | Kunci join tidak bisa dipakai |
Berkas Latihan dan Bentuknya #
Dua berkas latihan disusun menyerupai ekspor nyata: total 218 baris dengan produk, pelanggan, dan status yang masuk akal. Kotoran sengaja ditanam dengan jumlah yang tercatat, sehingga setiap aturan pipeline punya contoh hidup dan setiap angka pada Bagian 9 dapat dijelaskan:
| Berkas | Baris | Baris galat | Baris kotor tetapi valid | Duplikat tertanam |
|---|---|---|---|---|
pesanan_2024-06.csv | 107 | 16 | 3 | 2 persis |
pesanan_2024-07.csv | 111 | 5 | 2 | 2 persis, 3 lintas berkas, 1 konflik |
Kolom terakhir pada tabel di atas adalah cerita tersendiri. Sistem sumber mengekspor ulang beberapa pesanan akhir Juni ke dalam berkas Juli, dan salah satu ekspor ulang membawa revisi isi yang berbeda dari catatan pertamanya.
Alat dan Prasyarat #
Proyek ini sengaja tidak memakai dependensi berat. Seluruh kebutuhan sudah tersedia di lingkungan tutorial:
| Alat | Peran |
|---|---|
| Python 3.12 | runtime seluruh modul |
csv, re, sqlite3 dari stdlib | pembacaan, pola, dan basisdata lokal |
| pytest | kerangka pengujian |
| PyYAML | pembacaan config/pipeline.yaml |
Nomor versi boleh berbeda di komputer Anda; yang dijaga adalah kompatibilitasnya, bukan angka persisnya.
Kebutuhan dan Kriteria Berhasil #
Dari audit di atas, kita menurunkan kebutuhan menjadi kriteria yang dapat diuji. Setiap baris pada tabel berikut akan diperiksa lagi di Bagian 9:
| Kebutuhan | Kriteria terukur |
|---|---|
| Satu pesanan satu baris | 0 baris ganda di tabel akhir |
| Hanya data sehat yang masuk | Baris gagal validasi ditolak dan dicatat, bukan diperbaiki diam-diam |
| Nilai konsisten | Satu kategori satu ejaan; satu status satu ejaan; angka tanpa pemisah ribuan |
| Tipe data benar | jumlah dan harga bertipe integer, bukan teks |
| Bisa dijalankan ulang | Menjalankan pipeline dua kali tidak menambah baris tabel |
| Terlacak | Setiap keputusan (tolak, buang, muat) tercatat di log |
| Dapat diverifikasi | Jumlah baris tabel dapat dihitung dan cocok dengan ringkasan pipeline |
Dua kebutuhan terakhir menuntut perhatian khusus. Kata terlacak berarti keputusan yang sama harus menghasilkan jejak yang sama, sehingga kita tahu persis baris mana yang dibuang dan alasannya. Kata dapat dijalankan ulang adalah definisi idempotent yang kita pelajari di Idempotency dan Retries: hasil akhirnya sama, berapa kali pun diulang.
Lingkup dan Batasan #
Yang masuk lingkup proyek ini:
- membaca seluruh berkas
data/pesanan_*.csv, - validasi, pembersihan, dan deduplikasi dalam proses Python,
- pemuatan ke tabel
pesanandengan UPSERT per batch, - logging ke konsol dan berkas,
- pengujian pytest untuk semua lapisan.
Yang sengaja tidak masuk lingkup:
- perubahan data di sumber (kita tidak menyentuh sistem warisan),
- orkestrasi terjadwal dan retry otomatis,
- transformasi analitik lanjutan seperti agregasi harian.
Batasan lingkungan juga perlu diakui sejak awal. Server PostgreSQL tidak tersedia di lingkungan tutorial, sehingga pemuatan yang dijalankan nyata memakai SQLite sebagai kembaran lokal dengan pola SQL yang sama. Modul khusus PostgreSQL tetap disediakan dan diverifikasi sampai kompilasi; penjelasannya ada di Bagian 5.
Cara Membaca Bagian-Bagian Berikutnya #
Tiga kesepakatan berlaku untuk seluruh bagian proyek ini:
- setiap blok Output yang Dihasilkan adalah hasil eksekusi nyata di lingkungan tutorial, bukan contoh karangan;
- setiap cuplikan kode diambil dari berkas yang benar-benar ada di
src/,tests/, atauconfig/, dan dapat diunduh dari bagian Berkas Sumber; - judul chapter lain yang ditulis miring adalah rujukan silang ke materi pendukung, bukan hiasan kalimat.
Dengan tiga kesepakatan tersebut, angka pada satu bagian selalu dapat diperiksa ulang dari berkas sumbernya.
Peta Sembilan Bagian #
Urutan pengerjaan mengikuti alur data, bukan urutan kenyamanan menulis kode:
- Bagian 2 merancang skema tabel: tipe, constraint, dan index.
- Bagian 3 membaca dan memvalidasi CSV.
- Bagian 4 membersihkan baris yang lolos validasi.
- Bagian 5 memuat hasil bersih dengan upsert.
- Bagian 6 menangani duplikat lintas berkas.
- Bagian 7 menambahkan logging pada seluruh tahap.
- Bagian 8 menguji semua lapisan dengan pytest.
- Bagian 9 menjalankan pipeline utuh dan membaca hasilnya.
Urutan ini penting karena keputusan skema pada Bagian 2 menjadi rujukan tipe data pada pembersihan Bagian 4 dan pola upsert pada Bagian 5. Materi pendukungnya telah kita bahas di CSV untuk format sumber dan akan diperdalam di Deduplikasi Data serta Pengujian Kode Python.
Dengan kebutuhan yang sudah terukur, langkah berikutnya adalah memberi rumah bagi data tersebut: merancang skema database yang menegakkan aturan sejak tingkat tabel. Lanjutkan ke Bagian 2: Merancang Skema Database.