HOWTO · MongoDB
How to Locally Connect to a MongoDB Database Using Python
In this Python MongoDB tutorial, you will learn the basics of PyMongo, how to connect a MongoDB database locally using Python, and perform some simple database operations.
On this page
Use PyMongo, MongoDB’s Python driver, to connect to a MongoDB deployment, choose a database and collection, and insert or query BSON documents. The workflow below uses a MongoDB URI and a small shopping-list collection. Replace the URI placeholders with your deployment’s connection details, and keep credentials out of source control. (insert_many(); insert_one())
Install Python and PyMongo
Install Python, then install PyMongo with python -m pip install pymongo. The example uses a DNS seed-list URI beginning with mongodb+srv://; install its DNS support with python -m pip install "pymongo[srv]" (or install dnspython separately). If your deployment gives you a standard mongodb:// URI, use that URI and follow its network and authentication settings.
Save the program as pymongo_example.py and run the local demonstration with python pymongo_example.py. To run the database workflow, first set MONGODB_URI to the connection string from your MongoDB deployment, then pass --database. For macOS or Linux, use export MONGODB_URI='mongodb+srv://<username>:<password>@<cluster-name>/'; in PowerShell, use $env:MONGODB_URI = 'mongodb+srv://<username>:<password>@<cluster-name>/'. Replace the placeholders, URL-encode special characters in credentials as required by the URI format, and do not put a real credential in source control or a shared shell history. Run python pymongo_example.py --database. The same filename appears in both the save path and command.
Connect to MongoDB with PyMongo
Create a MongoClient with the URI supplied by your MongoDB deployment. A seed-list URI includes the cluster host and may include authentication options; replace <username>, <password>, and <cluster-name> rather than copying them literally. Avoid printing the URI because it can contain credentials. The database branch below is selected only by --database and reads the URI from MONGODB_URI; without that flag, the program runs its separate offline demonstration and does not contact MongoDB.
In the application, read the URI from an environment variable such as MONGODB_URI, then pass it to MongoClient. For a script, put work under a module-level if __name__ == "__main__": guard so importing the file does not start database operations. MongoClient connects lazily, so a client can be constructed before the first database operation; the first operation is where network, DNS, authentication, and server-selection problems commonly appear. Close the client when the work is finished, or use a context manager for a short-lived script.
Create a database and collection
Select a database with client["user_shopping_list"] and a collection with database["items"]. These expressions select handles; they do not by themselves create persisted database or collection data. MongoDB creates them when an insert first writes data. Use stable names consistently in the insert and query steps.
Insert documents
A Python dictionary maps naturally to a MongoDB document. The database example uses collection.insert_many(documents) for two documents and collection.insert_one(document) for a third. The single document includes a timezone-aware Python datetime.datetime value, which PyMongo encodes as a BSON date. The returned result objects provide inserted identifiers for querying the documents just written. Omit _id when you want MongoDB to generate it; this example assigns unique IDs so the query can target its own inserted records.
The insertion calls require a reachable MongoDB deployment and write permission. Avoid rerunning sample inserts against a shared database unless duplicate records are acceptable or the example uses stable identifiers and handles duplicate-key errors.
Query documents and handle missing fields
Use collection.find({}) to iterate over all documents, or pass a filter such as {"category": "food"} to select matching documents. Each result is dictionary-like. A direct lookup such as item["category"] produces a KeyError when that document lacks the key; use item.get("category", "(not set)") when a fallback is appropriate. MongoDB’s find() returns a cursor, so iterate over it rather than treating it as one document.
Run this local demonstration to see how the display handles documents with different fields. It is offline; the database workflow is enabled separately with --database and MONGODB_URI as described above.
import os
import sys
import uuid
from datetime import datetime, timezone
def show_documents(documents):
for item in documents:
print(item["item_name"], item.get("category", "(not set)"))
def run_database_workflow():
from pymongo import MongoClient
uri = os.environ.get("MONGODB_URI")
if not uri:
print("Set MONGODB_URI before running with --database.")
return
with MongoClient(uri) as client:
collection = client["user_shopping_list"]["items"]
many = [
{"_id": str(uuid.uuid4()), "item_name": "Bread", "category": "food"},
{"_id": str(uuid.uuid4()), "item_name": "Blender"},
]
many_result = collection.insert_many(many)
single = {
"_id": str(uuid.uuid4()),
"item_name": "Coffee",
"category": "food",
"added_at": datetime.now(timezone.utc),
}
single_result = collection.insert_one(single)
inserted_ids = many_result.inserted_ids + [single_result.inserted_id]
found = collection.find({"_id": {"$in": inserted_ids}})
show_documents(found)
def main():
if "--database" in sys.argv:
run_database_workflow()
else:
# This local sample needs no MongoDB server or connection URI.
show_documents([
{"item_name": "Bread", "category": "food"},
{"item_name": "Blender"},
])
if __name__ == "__main__":
main()
Bread food
Blender (not set)
The local example’s output is:
In the database workflow, the same safe access pattern runs while iterating over the cursor returned by find(). If a query returns no documents, the cursor simply yields no rows; check the filter and collection name before assuming the connection failed. Importing this module defines its functions but does not call main() or perform database operations.