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

  1. Install Python from the official website and check it with python --version.
  2. Create a project folder and open a terminal inside it.
  3. Run pip install pymongo to add the driver.
  4. 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

  • MongoClient manages 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

TaskShell CommandPyMongo Method
Insert oneinsertOneinsert_one
Insert manyinsertManyinsert_many
Find onefindOnefind_one
Update oneupdateOneupdate_one
Delete manydeleteManydelete_many
CountcountDocumentscount_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.