Driver menyediakan operasi yang sama di bahasa pemrograman apa pun, dan Python menggunakan driver resminya bernama PyMongo. Topik ini membangun ulang siklus CRUD dari modul ini di atas PyMongo, mulai dari pembuatan klien, operasi create, read, update, dan delete, sampai padanan metode antara driver Node.js dan PyMongo. Koleksi yang dipakai tetap pekerjaan pada basis data tugas, yaitu daftar pekerjaan pribadi, sehingga keluaran program Python dapat dibandingkan baris demi baris dengan keluaran program Node.js. Setelah mengikuti topik ini, pola yang sama dapat dipindahkan antar kedua bahasa sesuai kebutuhan proyek.
Koneksi dengan MongoClient#
PyMongo dipasang melalui pip install pymongo, dan lingkungan latihan jalur ini sudah memuatnya secara global untuk python3. Klien dibuat dari kelas MongoClient dengan connection string yang sama dengan driver Node.js, yaitu mongodb://127.0.0.1:27017 untuk server lokal tanpa autentikasi. Berbeda dari driver Node.js, PyMongo tidak memerlukan pemanggilan connect() eksplisit. Hubungan ke server baru dibangun pada saat operasi pertama dieksekusi, sehingga pembuatan klien di awal program tidak mengirim apa pun ke jaringan.
Akses basis data dan koleksi menggunakan kurung siku, misalnya client["tugas"]["pekerjaan"], dan bentuk ini memetakan langsung ke client.db() dan db.collection() pada driver Node.js. Sebagaimana di shell, nama basis data dan koleksi tidak perlu dibuat terlebih dahulu, karena MongoDB menyediakannya saat dokumen pertama disisipkan. Satu objek MongoClient aman dipakai bersama oleh banyak thread, sehingga satu klien cukup untuk seluruh proses dan dibuat sedini mungkin. Opsi koneksi ditambahkan sebagai argumen kata kunci pada konstruktor, misalnya serverSelectionTimeoutMS=2000 untuk membatasi waktu pemilihan server. Metode client.close() menutup kumpulan koneksi secara tertib setelah seluruh operasi selesai, dan pemanggilannya terlihat pada akhir program contoh.
Menjalankan CRUD dari aplikasi.py#
Program aplikasi.py menjalankan alur yang sama dengan program Node.js pada modul ini, yaitu reset koleksi, penyisipan empat dokumen, penyisipan satu dokumen tambahan, pembacaan satu dokumen dengan urutan, pembacaan seluruh dokumen dengan proyeksi, pembaruan satu field, penghapusan, dan penghitungan akhir. Seluruh metodenya sinkron, sehingga kode berjalan baris demi baris tanpa await maupun fungsi async. Nama metodenya mengikuti gaya snake_case, yaitu huruf kecil yang dipisah garis bawah, sebagaimana konvensi penamaan Python.
# CRUD pekerjaan pribadi dari aplikasi Python dengan PyMongo
from pymongo import MongoClient
client = MongoClient("mongodb://127.0.0.1:27017")
koleksi = client["tugas"]["pekerjaan"]
# koleksi di-reset agar keluaran program selalu sama
koleksi.delete_many({})
# CREATE: menyisipkan banyak dokumen sekaligus
seed = koleksi.insert_many([
{"judul": "Belanja mingguan", "kategori": "rumah", "prioritas": 2, "selesai": False},
{"judul": "Kirim dokumen pajak", "kategori": "pribadi", "prioritas": 1, "selesai": False},
{"judul": "Ganti filter air", "kategori": "rumah", "prioritas": 3, "selesai": False},
{"judul": "Baca artikel basis data", "kategori": "belajar", "prioritas": 5, "selesai": True},
])
print("Dokumen baru:", len(seed.inserted_ids))
# CREATE: menyisipkan satu dokumen tambahan
koleksi.insert_one({"judul": "Rapikan arsip foto", "kategori": "pribadi", "prioritas": 4, "selesai": False})
# READ: membaca satu dokumen pertama yang cocok dengan filter
pajak = koleksi.find_one({"kategori": "pribadi"}, sort=[("prioritas", 1)])
print("Pertama pribadi:", pajak["judul"])
# READ: membaca seluruh dokumen dengan proyeksi
for d in koleksi.find({}, {"_id": 0, "judul": 1, "selesai": 1}).sort("prioritas", 1):
tanda = "x" if d["selesai"] else " "
print("[" + tanda + "] " + d["judul"])
# UPDATE: menandai satu pekerjaan selesai
ubah = koleksi.update_one({"judul": "Belanja mingguan"}, {"$set": {"selesai": True}})
print("Dokumen diubah:", ubah.modified_count)
# DELETE: menghapus satu pekerjaan yang tidak dibutuhkan lagi
hapus = koleksi.delete_one({"judul": "Ganti filter air"})
print("Dokumen dihapus:", hapus.deleted_count)
print("Sisa dokumen:", koleksi.count_documents({}))
client.close()Dokumen baru: 4
Pertama pribadi: Kirim dokumen pajak
[ ] Kirim dokumen pajak
[ ] Belanja mingguan
[ ] Ganti filter air
[ ] Rapikan arsip foto
[x] Baca artikel basis data
Dokumen diubah: 1
Dokumen dihapus: 1
Sisa dokumen: 4Keluaran program identik dengan keluaran program Node.js hingga baris terakhir, karena keduanya menjalankan operasi yang sama pada data yang sama. Nilai prioritas berupa bilangan bulat, sehingga perbedaan pencetakan bilangan pecahan antar kedua bahasa tidak muncul di sini. Bagian yang berbeda justru ada pada kode sumbernya, yaitu penamaan metode bergaya snake_case seperti insert_many dan update_one, atribut hasil seperti modified_count, serta proyeksi dalam bentuk dict biasa.
Program dijalankan dari folder topik dengan python3, tanpa penyiapan variabel tambahan karena PyMongo sudah terpasang secara global.
# menjalankan program PyMongo dari folder topik
python3 aplikasi.pyDokumen baru: 4
Pertama pribadi: Kirim dokumen pajak
[ ] Kirim dokumen pajak
[ ] Belanja mingguan
[ ] Ganti filter air
[ ] Rapikan arsip foto
[x] Baca artikel basis data
Dokumen diubah: 1
Dokumen dihapus: 1
Sisa dokumen: 4Hasil eksekusi bash menegaskan bahwa program bersifat mandiri, yaitu menanam datanya sendiri dan menghasilkan keluaran yang sama setiap kali dijalankan. Sifat ini berlaku untuk seluruh program pada modul ini dan membuat variasi kode dapat diuji dengan pembanding yang tetap.
Padanan metode kedua driver#
Perbedaan penamaan antara kedua driver mengikuti konvensi bahasanya masing-masing, yaitu camelCase pada JavaScript dan snake_case pada Python. Struktur data pendukungnya juga menyesuaikan. Daftar pasangan seperti sort=[("prioritas", 1)] menggantikan objek { prioritas: 1 }. Sebaliknya, filter dan operator update tidak berubah sama sekali, karena $set, $gte, dan operator lain dieksekusi server dengan makna yang sama. Perbedaan ejaannya hanya terjadi pada nama metode dan atribut hasil, sedangkan isi argumen filter dan proyeksinya dapat disalin apa adanya. Tabel berikut merangkum padanan yang paling sering digunakan.
| Kebutuhan | Driver Node.js | PyMongo |
|---|---|---|
| menyisipkan banyak dokumen | insertMany() | insert_many() |
| membaca satu dokumen | findOne() | find_one() |
| mengubah satu dokumen | updateOne() | update_one() |
| menghapus satu dokumen | deleteOne() | delete_one() |
| menghitung dokumen | countDocuments() | count_documents() |
| hasil update satu dokumen | result.modifiedCount | result.modified_count |
| hasil insert banyak dokumen | result.insertedCount | len(result.inserted_ids) |
| urutan pada pembacaan tunggal | findOne(filter, { sort: ... }) | find_one(filter, sort=[...]) |
Ketika kode berpindah antar kedua bahasa, operator dan filter menyeberang tanpa suntingan, sedangkan nama metode dan bentuk opsi yang perlu diubah. Proyeksi pembacaan tidak ikut berubah bentuk, sehingga dokumen {"_id": 0, "judul": 1} yang sama diterima kedua driver. Kursor yang dikembalikan find() juga diiterasi langsung dengan for pada Python, tanpa pemanggilan toArray() yang diperlukan di Node.js. Pengulangan tersebut menghasilkan urutan dokumen yang sama karena penyortirannya dilakukan oleh server. Padanan yang jarang digunakan cukup dicari pada dokumentasi masing-masing driver, dan pola penamaannya selalu sama.
Kesalahan umum#
Kesalahan pertama adalah menggunakan string heksadesimal untuk mencocokkan _id bertipe ObjectId. Filter {"_id": "672f..."} tidak pernah cocok, karena tipe string berbeda dari tipe ObjectId pada BSON. Konversinya dilakukan dengan kelas ObjectId dari package bson yang ikut terpasang bersama PyMongo, yaitu ObjectId("672f..."), sebelum filter dikirim. Kesalahan senyap yang serupa juga muncul pada field bernilai tanggal atau angka, karena pencocokan gagal tanpa pesan apa pun ketika tipenya berbeda.
Kesalahan kedua adalah menganggap insert_many menyimpan sebagian dokumen lalu melanjutkan ketika satu dokumen ditolak server. Secara bawaan parameter ordered bernilai True, sehingga penyisipan berhenti pada dokumen pertama yang gagal. Dokumen sebelumnya tetap tersimpan, sedangkan dokumen sesudahnya tidak pernah dikirim. Nilai ordered=False membuat server melanjutkan dokumen berikutnya dan mengumpulkan error untuk diperiksa setelah operasi selesai.
Kesalahan ketiga adalah menggunakan PyMongo di dalam framework web asinkron seperti FastAPI. Setiap panggilan PyMongo bersifat sinkron dan menahan event loop, yaitu mekanisme yang mengatur eksekusi kode asinkron, selama operasi berlangsung. Akibatnya aplikasi terasa lambat pada trafik tinggi. Pilihan yang tepat adalah driver asinkron Motor, yang mengekspos operasi yang sama dalam bentuk await tanpa mengubah filter maupun struktur dokumennya.
Ringkasan#
- PyMongo menggunakan connection string yang sama dengan driver Node.js, tanpa
connect()eksplisit karena koneksi baru dibangun saat operasi pertama. - Metodenya mengikuti gaya snake_case, yaitu
insert_many,find_one,update_one,delete_one, dancount_documents, dengan filter dan operator yang tetap identik. - Hasil operasi dibaca dari atribut seperti
modified_countdandeleted_count, sedangkaninsert_manymengembalikan daftarinserted_ids. - PyMongo bersifat sinkron, sehingga aplikasi asinkron memerlukan driver Motor untuk operasi berbasis
await.
Referensi#
- PyMongo — MongoDB Documentation — Dokumentasi resmi PyMongo, termasuk referensi metode koleksi.
- Get Started with PyMongo — MongoDB Documentation — Pemasangan PyMongo dan program pertama dari Python.
- CRUD Operations — PyMongo Driver — Panduan operasi create, read, update, dan delete pada PyMongo.
- Connect to MongoDB — PyMongo Driver
— Pembuatan
MongoClientdan opsi koneksi pada PyMongo. - Connection String URI Format — MongoDB Manual — Format connection string yang dipakai driver MongoDB di semua bahasa.