Empat babahan sudah kita kuasai: membuat tabel (Chapter SQL Dasar untuk Python), membuka koneksi (Chapter SQLite dengan Python), mengambil hasil (Chapter Koneksi dan Cursor), dan mengikat nilai dengan aman (Chapter Parameterized Queries). Saatnya merakit semuanya menjadi satu program utuh. Industri menyebut empat operasi pokok database dengan istilah CRUD: Create, Read, Update, Delete — hampir semua aplikasi data, dari catatan harian sampai sistem kasir, dibangun di atas keempat operasi ini.

Merancang Struktur Program #

Program kita mengelola tabel produk inventaris toko dengan prinsip sederhana: setiap operasi CRUD menjadi satu fungsi. Fungsi menerima objek conn sebagai argument pertama, menjalankan satu pernyataan SQL dengan placeholder, memanggil commit(), lalu mengembalikan informasi berguna:

  • tambah_produk() mengembalikan cursor.lastrowid — id yang diberikan SQLite pada baris baru.
  • perbarui_stok() dan hapus_produk() mengembalikan cursor.rowcount — jumlah baris yang tersentuh.
  • semua_produk() mengembalikan seluruh baris untuk ditampilkan.

Nilai kembalian ini penting: pemanggil fungsi langsung tahu operasinya berhasil atau tidak tanpa harus query ulang.

Program Lengkap #

Simpan program berikut sebagai crud.py, lalu jalankan dengan python3 crud.py:

python
from pathlib import Path
import sqlite3

DB_PATH = "toko.db"

def buat_koneksi():
    return sqlite3.connect(DB_PATH)

def init_db(conn):
    conn.execute("""CREATE TABLE IF NOT EXISTS produk (
        id INTEGER PRIMARY KEY,
        nama TEXT NOT NULL,
        harga REAL NOT NULL,
        stok INTEGER NOT NULL DEFAULT 0
    )""")

def tambah_produk(conn, nama, harga, stok):
    cursor = conn.execute(
        "INSERT INTO produk (nama, harga, stok) VALUES (?, ?, ?)",
        (nama, harga, stok),
    )
    conn.commit()
    return cursor.lastrowid

def semua_produk(conn):
    return conn.execute(
        "SELECT id, nama, harga, stok FROM produk ORDER BY nama"
    ).fetchall()

def perbarui_stok(conn, produk_id, stok_baru):
    cursor = conn.execute(
        "UPDATE produk SET stok = ? WHERE id = ?",
        (stok_baru, produk_id),
    )
    conn.commit()
    return cursor.rowcount

def hapus_produk(conn, produk_id):
    cursor = conn.execute("DELETE FROM produk WHERE id = ?", (produk_id,))
    conn.commit()
    return cursor.rowcount

def tampilkan(baris_data):
    print(f"{'ID':<4}{'Nama':<20}{'Harga':>12}{'Stok':>6}")
    for id_, nama, harga, stok in baris_data:
        print(f"{id_:<4}{nama:<20}{harga:>12.0f}{stok:>6}")

Path(DB_PATH).unlink(missing_ok=True)  # mulai bersih agar demo dapat diulang
conn = buat_koneksi()
init_db(conn)

id_kopi = tambah_produk(conn, "Kopi Hitam 200g", 18000, 12)
id_teh = tambah_produk(conn, "Teh Celup Isi 25", 9500, 30)
id_gula = tambah_produk(conn, "Gula Pasir 1kg", 15500, 25)
print(f"[CREATE] produk baru: Kopi({id_kopi}), Teh({id_teh}), Gula({id_gula})")

print("[READ] daftar produk:")
tampilkan(semua_produk(conn))

print(f"[UPDATE] baris terubah: {perbarui_stok(conn, id_teh, 40)}")
print("[READ] setelah stok Teh Celup diperbarui:")
tampilkan(semua_produk(conn))

print(f"[DELETE] baris terhapus: {hapus_produk(conn, id_gula)}")
print("[READ] setelah Gula Pasir dihapus:")
tampilkan(semua_produk(conn))

conn.close()

Output yang Dihasilkan:

text
[CREATE] produk baru: Kopi(1), Teh(2), Gula(3)
[READ] daftar produk:
ID  Nama                       Harga  Stok
3   Gula Pasir 1kg             15500    25
1   Kopi Hitam 200g            18000    12
2   Teh Celup Isi 25            9500    30
[UPDATE] baris terubah: 1
[READ] setelah stok Teh Celup diperbarui:
ID  Nama                       Harga  Stok
3   Gula Pasir 1kg             15500    25
1   Kopi Hitam 200g            18000    12
2   Teh Celup Isi 25            9500    40
[DELETE] baris terhapus: 1
[READ] setelah Gula Pasir dihapus:
ID  Nama                       Harga  Stok
1   Kopi Hitam 200g            18000    12
2   Teh Celup Isi 25            9500    40

Bedah Operasi Inti #

Transkrip di atas adalah siklus CRUD lengkap yang benar-benar berjalan. Mari kita bedah bagian intinya:

  1. Baris 17-23 (def tambah_produk(...)): satu INSERT dengan tiga placeholder. Atribut cursor.lastrowid membalas id yang dibuat SQLite — terbukti Kopi mendapat 1, Teh 2, Gula 3 pada transkrip.
  2. Baris 25-28 (def semua_produk(...)): SELECT dengan ORDER BY nama, sehingga tabel selalu tampil terurut alfabetis seperti pada transkrip (Gula, Kopi, Teh).
  3. Baris 30-36 (def perbarui_stok(...)): UPDATE menargetkan satu baris lewat WHERE id = ?; nilai kembalian rowcount 1 membuktikan tepat satu baris berubah — stok Teh dari 30 menjadi 40.
  4. Baris 38-41 (def hapus_produk(...)): DELETE berpola sama, dan rowcount 1 memastikan Gula Pasir sungguh hilang dari daftar terakhir.
  5. Baris 48-58 (alur utama): baris unlink() me-reset file demo, tiga tambah_produk() menyiapkan data, lalu setiap perubahan langsung diverifikasi dengan tampilkan(semua_produk(conn)) — kebiasaan membaca kembali setelah menulis.

Pemisahan fungsi seperti ini menjadikan tiap operasi bisa diuji sendiri-sendiri: cukup siapkan koneksi ke database :memory: di test, panggil satu fungsi, bandingkan hasilnya.

Peta Operasi CRUD #

OperasiPerintah SQLFungsiUmpan balik kembali
CreateINSERT INTO ...tambah_produk()cursor.lastrowid
ReadSELECT ...semua_produk()list baris
UpdateUPDATE ... SET ...perbarui_stok()cursor.rowcount
DeleteDELETE FROM ...hapus_produk()cursor.rowcount

Program ini adalah versi belajar. Versi aplikasi lengkap dengan pencarian, laporan, validasi, dan test otomatis kita bangun pada Proyek Aplikasi Inventaris SQLite di section proyek.