Saat mengolah data untuk analisis, kamu biasanya dihadapkan pada dua pilihan: memakai library DataFrame seperti Pandas atau Polars, atau menyiapkan database server seperti PostgreSQL. DuckDB menawarkan jalan ketiga: sebuah database analitik (OLAP) embedded yang bisa kamu pakai langsung dari Python tanpa menginstal server apa pun, sekaligus sanggup memproses jutaan baris dengan sangat cepat berkat mesin columnar-nya. Di tutorial ini kita akan mempelajari DuckDB dari nol sampai bisa menganalisis data nyata.

Apa Itu DuckDB?

DuckDB adalah in-process analytical database yang populer disebut sebagai “SQLite untuk analitik”. Bedanya dengan SQLite: SQLite dirancang untuk transaksi (OLTP), sedangkan DuckDB dirancang untuk kueri analitik (OLAP) — agregasi, penggabungan, dan pemindaian kolom berukuran besar. Karena bersifat embedded, kamu tidak perlu menjalankan server terpisah; data tersimpan dalam satu file .duckdb atau bahkan hanya di memori.

DuckDB juga bisa membaca langsung file CSV, Parquet, JSON, hingga tabel SQLite tanpa perlu import manual. Ini menjadikannya alat favorit untuk data exploration dan pipeline ETL ringan.

Persiapan: Install DuckDB

Pastikan kamu sudah punya Python 3.8 ke atas (lihat panduan install Python jika belum). Lalu install paket duckdb lewat pip:

bash
pip install duckdb
# atau dengan uv
uv add duckdb

Setelah terpasang, kita bisa langsung mencobanya. Paket ini tidak membutuhkan dependensi eksternal lain, jadi proses instalasinya cepat dan ringan.

Koneksi dan Query Dasar

DuckDB bisa dipakai lewat dua cara: koneksi eksplisit (mirip sqlite3) atau fungsi duckdb.sql() untuk satu baris kueri. Mari mulai dari koneksi in-memory:

python
import duckdb

# 1) Koneksi in-memory (hilang saat program selesai)
con = duckdb.connect()

# 2) Koneksi ke file persisten
# con = duckdb.connect("analitik.duckdb")

hasil = con.execute("SELECT 'Halo DuckDB!' AS pesan").fetchall()
print(hasil)  # [('Halo DuckDB!',)]

Untuk kueri cepat tanpa objek koneksi, gunakan duckdb.sql() yang langsung mengembalikan hasil. Metode .df() mengubah hasil kueri menjadi DataFrame Pandas, sementara .fetchall() mengembalikan daftar tuple:

python
import duckdb

# Kueri sekali jalan, hasil langsung jadi DataFrame Pandas
df = duckdb.sql("SELECT 1 + 1 AS hasil, 'dua' AS kata").df()
print(df)

Query Langsung dari File CSV & Parquet

Fitur paling keren dari DuckDB adalah kemampuannya membaca file data secara langsung lewat SQL — tanpa perlu membuat tabel dulu. Coba buat file penjualan.csv berikut, lalu query langsung dari file tersebut:

bash
cat > penjualan.csv <<'EOF'
id,produk,kategori,jumlah,harga
1,Laptop,Elektronik,5,12000000
2,Mouse,Elektronik,20,150000
3,Meja,Furnitur,3,800000
4,Keyboard,Elektronik,15,400000
5,Kursi,Furnitur,7,1500000
EOF
python
import duckdb

# Baca CSV langsung dari file, tanpa membuat tabel
hasil = duckdb.sql("""
    SELECT kategori,
           SUM(jumlah) AS total_terjual,
           SUM(jumlah * harga) AS total_pendapatan
    FROM 'penjualan.csv'
    GROUP BY kategori
    ORDER BY total_pendapatan DESC
""").df()

print(hasil)

DuckDB mendeteksi skema dan tipe kolom secara otomatis saat membaca CSV/Parquet. Untuk file Parquet, tinggal ganti 'penjualan.csv' menjadi 'data.parquet' — sintaksnya sama persis.

Integrasi dengan Pandas & Polars

DuckDB bisa membaca DataFrame yang sudah ada di memori dan menjalankan SQL di atasnya. Ini sangat berguna ketika kamu sudah punya data di Pandas atau Polars lalu ingin agregasi yang lebih ekspresif lewat SQL:

python
import pandas as pd
import duckdb

df = pd.DataFrame({
    "nama": ["Andi", "Budi", "Citra", "Dewi"],
    "usia": [25, 30, 22, 27],
    "kota": ["Jakarta", "Bandung", "Jakarta", "Surabaya"]
})

con = duckdb.connect()
con.register("pengguna", df)  # daftarkan DataFrame sebagai tabel 'pengguna'

hasil = con.execute("""
    SELECT kota, COUNT(*) AS jumlah, AVG(usia) AS rata_rata_usia
    FROM pengguna
    GROUP BY kota
    ORDER BY jumlah DESC
""").df()

print(hasil)

Hal yang sama juga berlaku untuk DataFrame Polars, sehingga kamu bisa memadukan kecepatan Polars dengan fleksibilitas SQL DuckDB:

python
import polars as pl
import duckdb

df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})

con = duckdb.connect()
con.register("data_polars", df)

print(con.execute("SELECT a, b, a * b AS hasil_kali FROM data_polars").df())

Membuat Tabel dan Analisis Lebih Lanjut

Untuk data yang perlu disimpan permanen, gunakan koneksi file .duckdb. Kita bisa membuat tabel, mengisinya, lalu memakai window function untuk analisis peringkat:

python
import duckdb

con = duckdb.connect("analitik.duckdb")  # file database persisten

con.execute("""
    CREATE TABLE IF NOT EXISTS penjualan (
        id INTEGER,
        produk VARCHAR,
        kategori VARCHAR,
        jumlah INTEGER,
        harga DECIMAL(12,2)
    )
""")

con.execute("""
    INSERT INTO penjualan VALUES
    (1, 'Laptop',  'Elektronik', 5,  12000000),
    (2, 'Mouse',   'Elektronik', 20, 150000),
    (3, 'Meja',    'Furnitur',   3,  800000),
    (4, 'Keyboard','Elektronik', 15, 400000),
    (5, 'Kursi',   'Furnitur',   7,  1500000)
""")

# Window function: peringkat produk berdasarkan jumlah terjual per kategori
peringkat = con.execute("""
    SELECT produk, kategori, jumlah,
           RANK() OVER (PARTITION BY kategori ORDER BY jumlah DESC) AS peringkat
    FROM penjualan
    ORDER BY kategori, peringkat
""").df()

print(peringkat)
con.close()

Saat memakai koneksi file .duckdb, jangan lupa memanggil con.close() agar data benar-benar ter-flush ke disk. Cara lebih aman adalah memakai with duckdb.connect(...) as con: yang menutup koneksi otomatis.

Kesimpulan

DuckDB memberi kamu kekuatan SQL analitik tanpa ribetnya mengelola server database. Cukup satu library, kamu bisa membaca CSV/Parquet langsung, memadukan DataFrame Pandas dan Polars, serta menyimpan hasilnya dalam satu file .duckdb. Ini pilihan tepat untuk eksplorasi data, pembuatan laporan, hingga pipeline ETL ringan. Selamat mencoba dan selamat menganalisis data dengan lebih cepat! 🚀