MongoDB with Python
Python is one of the most popular languages for data work, web applications, and automation. MongoDB provides an official Python driver called PyMongo. The driver lets Python programs store, find, change, and delete documents. Python dictionaries match MongoDB documents closely, so the code feels natural from the first line.
How the Pieces Connect
+---------------+ +-----------------+ +----------------+
| Python script | ---> | PyMongo driver | ---> | MongoDB server |
| app.py | | (pip package) | | (database) |
| dictionaries | <--- | converts types | <--- | documents |
+---------------+ +-----------------+ +----------------+A Python dictionary such as {"name": "Pen", "price": 5} turns into a MongoDB document when it travels through the driver. Documents coming back turn into dictionaries again.
Set Up the Project
- Install Python from the official website and check it with
python --version. - Create a project folder and open a terminal inside it.
- Run
pip install pymongoto add the driver. - Create a file named
app.py.
Connect to the Database
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017")
db = client["shop"]
products = db["products"]
print("Connected. Databases:", client.list_database_names())Code Walkthrough
MongoClientmanages the connection and a pool of connections behind the scenes.client["shop"]selects the database named shop.db["products"]selects the collection named products.- MongoDB creates the database and collection when the first document arrives.
Run the program with python app.py.
CRUD Operations in Python
The method names use lowercase words joined by underscores, which follows the usual Python style.
Create
result = products.insert_one({"name": "Pen", "price": 5})
print("Inserted id:", result.inserted_id)
products.insert_many([
{"name": "Pencil", "price": 3},
{"name": "Ruler", "price": 12},
{"name": "Notebook", "price": 50}
])Read
one = products.find_one({"name": "Pen"})
print(one)
for item in products.find({"price": {"$lt": 20}}):
print(item["name"], item["price"])The find method returns a cursor, which works inside a normal for loop. Turn the cursor into a list with list(products.find()) when you need all results at once.
Sort, Limit, and Project
top3 = products.find({}, {"_id": 0, "name": 1, "price": 1}).sort("price", -1).limit(3)
for item in top3:
print(item)The second argument of find selects the fields to return. The sort method takes a field name and a direction, where -1 means descending order.
Update
products.update_one({"name": "Pen"}, {"$set": {"price": 6}})
products.update_many({"price": {"$lt": 5}}, {"$inc": {"price": 1}})Delete
products.delete_one({"name": "Ruler"})
products.delete_many({"price": {"$gt": 100}})Count Documents
total = products.count_documents({"price": {"$gte": 10}})
print(total)Check the Result Objects
Write commands return result objects that confirm what happened:
result = products.update_many({"price": {"$lt": 10}}, {"$set": {"onSale": True}})
print("Matched:", result.matched_count)
print("Changed:", result.modified_count)Work with ObjectId
MongoDB assigns an ObjectId to every document that has no _id. A search by id needs the ObjectId class from the bson package, which installs together with PyMongo:
from bson import ObjectId
doc = products.find_one({"_id": ObjectId("64b7f0c2a1b2c3d4e5f60718")})A plain text string does not match an ObjectId, so conversion matters.
Work with Dates
Python datetime objects convert to the MongoDB Date type automatically:
from datetime import datetime, timezone
products.insert_one({"name": "Marker", "createdAt": datetime.now(timezone.utc)})Aggregation in Python
An aggregation pipeline is a list of dictionaries:
pipeline = [
{"$match": {"price": {"$gt": 0}}},
{"$group": {"_id": None, "avgPrice": {"$avg": "$price"}, "count": {"$sum": 1}}}
]
for row in products.aggregate(pipeline):
print(row)Handle Errors
from pymongo.errors import DuplicateKeyError, PyMongoError
try:
products.insert_one({"_id": 1, "name": "Pen"})
products.insert_one({"_id": 1, "name": "Pencil"})
except DuplicateKeyError:
print("That _id already exists")
except PyMongoError as error:
print("Database error:", error)The driver raises specific error classes, so a program can react with a clear message to each kind of problem.
Keep Secrets Safe
Real connection strings contain passwords. Read them from an environment variable and keep them out of the source code:
import os
from pymongo import MongoClient
client = MongoClient(os.environ["MONGODB_URI"])Create the client once when the program starts and reuse it for every request. The driver handles connection pooling, and repeated client creation wastes time and server resources. Close the client with client.close() when the program ends.
Quick Reference
| Task | Shell Command | PyMongo Method |
|---|---|---|
| Insert one | insertOne | insert_one |
| Insert many | insertMany | insert_many |
| Find one | findOne | find_one |
| Update one | updateOne | update_one |
| Delete many | deleteMany | delete_many |
| Count | countDocuments | count_documents |
Summary
PyMongo connects Python programs to MongoDB with a small amount of code. A MongoClient opens the connection, and methods such as insert_one, find, update_one, and delete_one mirror the shell commands in Python style. Dictionaries represent documents, the bson package supplies ObjectId, and specific error classes help handle failures. Environment variables protect passwords, and one shared client serves the whole program.
