Seluruh section ini bersandar pada SQLite, dan itu bukan kebetulan: satu file, tanpa instalasi, tanpa server. Namun SQLite punya batas desain — penulis serentak yang dipaksa mengantre, dan tidak ada tempat bagi sepuluh karyawan yang mengakses database dari komputer berbeda. PostgreSQL dan MySQL adalah dua database server open source terpopuler di dunia, dan pertanyaan yang harus bisa kita jawab adalah kapan pindah serta seberapa besar kode kita yang harus berubah. Kabar baiknya: jawaban kedua adalah “hampir tidak ada”, berkat sebuah standar bernama DB-API.

Kapan Lulus dari SQLite #

KebutuhanSQLite memadai?Alasan
Data lokal untuk satu aplikasiyasatu file, nol konfigurasi
Prototipe dan belajar SQLyafokus ke materi, bukan instalasi
Banyak proses menulis serentaktidakSQLite mengunci seluruh file saat menulis
Akses dari banyak komputertidakSQLite tidak punya server jaringan
Jutaan baris dengan query beratmulai goyahserver DB punya optimizer dan cache yang lebih matang
Tipe data khusus (JSONB, array, spasial)terbatasPostgreSQL kaya tipe data modern

Pada database server, klien terhubung lewat jaringan ke satu proses server yang mengatur akses semua pengguna — inilah yang membuat tim kasir, gudang, dan akuntansi bisa bekerja di satu database yang sama.

Driver untuk PostgreSQL dan MySQL #

Python tidak membawa driver untuk kedua database ini di standard library, jadi kita memasangnya lewat pip:

DatabasePackageCatatan
SQLitesqlite3 (bawaan)tanpa instalasi
PostgreSQLpsycopg (versi 3)generasi terbaru; pip install psycopg
PostgreSQLpsycopg2pendahulu yang masih sangat luas dipakai
MySQLPyMySQLmurni Python; pip install pymysql
MySQLmysql-connector-pythondriver resmi dari Oracle

Untuk MariaDB (fork MySQL), driver MySQL seperti PyMySQL umumnya tetap kompatibel. Satu nama yang perlu diwaspadai adalah psycopg: tanpa angka berarti versi 3, sedangkan psycopg2 adalah paket berbeda dengan API serupa.

DB-API 2.0: Satu Pola untuk Semua #

PEP 249 mendefinisikan DB-API 2.0 — antarmuka standar Python untuk database. Semua driver serius mengikutinya, termasuk sqlite3 yang selama ini kita pakai. Kita bisa membuktikan keanggotaan module sqlite3 langsung:

python
import sqlite3

print("apilevel  :", sqlite3.apilevel)
print("paramstyle:", sqlite3.paramstyle)
print("threadsafety:", sqlite3.threadsafety)

Output yang Dihasilkan:

text
apilevel  : 2.0
paramstyle: qmark
threadsafety: 3

apilevel 2.0 berarti module mengikuti DB-API 2.0; paramstyle qmark adalah gaya placeholder ? yang kita kuasai sejak Chapter Parameterized Queries. Driver lain memakai paramstyle berbeda — psycopg dan PyMySQL memakai %s — tetapi kerangka kerjanya sama. Bandingkan tiga program berikut, dimulai dari SQLite yang bisa kita jalankan:

python
import sqlite3

conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE produk (nama TEXT, harga REAL)")
conn.execute("INSERT INTO produk VALUES ('Gula Pasir 1kg', 15500)")
conn.commit()

cursor = conn.execute("SELECT nama, harga FROM produk WHERE harga > ?", (10000,))
print(cursor.fetchall())
conn.close()

Output yang Dihasilkan:

text
[('Gula Pasir 1kg', 15500.0)]

Versi PostgreSQL-nya — ilustratif, karena membutuhkan server PostgreSQL dan pip install psycopg:

python
# Ilustratif — membutuhkan server PostgreSQL dan paket psycopg
import psycopg

info = "host=localhost dbname=toko user=admin password=YOUR_DATABASE_PASSWORD"
with psycopg.connect(info) as conn:
    with conn.cursor() as cur:
        cur.execute("SELECT nama, harga FROM produk WHERE harga > %s", (10000,))
        for nama, harga in cur.fetchall():
            print(nama, harga)

Versi MySQL-nya dengan PyMySQL — juga ilustratif:

python
# Ilustratif — membutuhkan server MySQL dan paket PyMySQL
import pymysql

conn = pymysql.connect(
    host="localhost",
    user="admin",
    password="YOUR_DATABASE_PASSWORD",
    database="toko",
)
try:
    with conn.cursor() as cur:
        cur.execute("SELECT nama, harga FROM produk WHERE harga > %s", (10000,))
        for baris in cur.fetchall():
            print(baris)
    conn.commit()
finally:
    conn.close()

Empat momen hidupnya persis sama — connect(), cursor() + execute(), fetch...(), lalu commit()/close() — hanya penamaan dan penanda parameter yang berganti. Kode akses data yang tertata rapi (seperti fungsi-fungsi CRUD pada Chapter CRUD dengan SQLite) biasanya hanya butuh perubahan pada lapisan pembukaan koneksi dan penulisan placeholder.

Deployment: Managed vs Self-Hosted #

Menjalankan database server ada dua jalur:

JalurWujudCocok untuk
Self-hostedkita pasang dan rawat PostgreSQL/MySQL di VPS sendirikendali penuh, biaya server tetap, tim punya sysadmin
Managedprovider awan (Amazon RDS, Cloud SQL, Neon, PlanetScale) yang mengurus serverbackup, patching, dan monitoring otomatis; tim kecil fokus ke aplikasi

Managed database membebaskan kita dari pekerjaan operasional, dengan imbal balik biaya berlangganan dan sedikit keterikatan pada penyedia. Untuk belajar, self-hosted di komputer sendiri tetap tak tertukar.

Tabel Keputusan #

Situasi AndaPilihan yang tepat
Aplikasi desktop, alat CLI, prototipe, test cepatSQLite
Aplikasi web kecil hingga menengah, satu timSQLite masih layak; PostgreSQL mulai nyaman
Banyak pengguna menulis serentak, data bisnis pentingPostgreSQL atau MySQL
Stack yang menyediakan MySQL (mis. WordPress)MySQL
Butuh tipe data kaya: JSONB, array, query spasialPostgreSQL

Pergeseran dari SQLite ke database server bukan lompatan besar, melainkan ganti mesin di balik antarmuka yang sudah kita kenal. Seluruh bekal section ini — SQL, placeholder, transaksi, migrasi, pengelolaan koneksi — ikut pindah bersama kita.