pymongo
mongodb
object id
insert operation
python programming

How to get the object id in PyMongo after an insert?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

In PyMongo, the usual way to get the inserted document's _id is to read result.inserted_id after insert_one(). If you insert multiple documents, use result.inserted_ids. That is the normal, supported API for retrieving the generated object IDs after an insert.

Single Insert with insert_one

When you insert one document, insert_one() returns an InsertOneResult object.

python
1from pymongo import MongoClient
2
3client = MongoClient("mongodb://localhost:27017/")
4collection = client.example_db.example_collection
5
6document = {"name": "John Doe", "age": 30}
7result = collection.insert_one(document)
8
9print(result.inserted_id)

result.inserted_id is the simplest and most direct answer to the question.

If the document did not already contain an _id, PyMongo creates one automatically before sending the insert to MongoDB.

The Original Document Also Gets an _id

A detail many developers miss is that PyMongo usually mutates the inserted document object by adding _id if it was missing.

python
1from pymongo import MongoClient
2
3client = MongoClient("mongodb://localhost:27017/")
4collection = client.example_db.people
5
6doc = {"name": "Alice"}
7result = collection.insert_one(doc)
8
9print(result.inserted_id)
10print(doc["_id"])

Those two values should refer to the same inserted identifier. In day-to-day code, result.inserted_id is clearer because it makes the source of the value obvious, but it is useful to know why the original dictionary appears to change.

Inserting Many Documents

For bulk inserts, insert_many() returns an InsertManyResult with a list of IDs.

python
1from pymongo import MongoClient
2
3client = MongoClient("mongodb://localhost:27017/")
4collection = client.example_db.people
5
6documents = [
7    {"name": "Alice", "age": 25},
8    {"name": "Bob", "age": 27},
9    {"name": "Charlie", "age": 28},
10]
11
12result = collection.insert_many(documents)
13print(result.inserted_ids)

This preserves the order of the inserted documents as represented by the result.

Custom _id Values

MongoDB does not force you to use the default ObjectId. If you provide your own _id, PyMongo uses it.

python
1from pymongo import MongoClient
2
3client = MongoClient("mongodb://localhost:27017/")
4collection = client.example_db.people
5
6doc = {"_id": "user-42", "name": "Dana"}
7result = collection.insert_one(doc)
8
9print(result.inserted_id)

This prints user-42. The important rule is that _id must be unique in the collection.

Convert the ID to a String Only When Needed

The inserted ID is often an ObjectId instance, not a plain string. That is fine, and you usually should keep it in that form until you actually need a string representation for JSON or logging.

python
1result = collection.insert_one({"name": "Eve"})
2object_id = result.inserted_id
3
4print(type(object_id))
5print(str(object_id))

Keeping the original type is useful because PyMongo queries accept ObjectId directly.

Using the Returned ID Immediately

One common follow-up is to use the inserted ID right away in another operation, such as a verification read or a redirect target in an API response.

python
result = collection.insert_one({"name": "Frank"})
saved = collection.find_one({"_id": result.inserted_id})
print(saved)

That works without any extra conversion because the returned value is already in the type PyMongo expects for _id lookups.

Handle Errors Explicitly

Insert operations can fail because of connectivity issues, validation rules, or duplicate _id values.

python
1from pymongo.errors import DuplicateKeyError
2
3try:
4    result = collection.insert_one({"_id": "user-42", "name": "Dana"})
5    print(result.inserted_id)
6except DuplicateKeyError:
7    print("That _id already exists")

This matters most when you assign custom _id values yourself or perform inserts into collections with additional unique constraints.

Common Pitfalls

The most common mistake is looking for the inserted ID on the collection object instead of on the result object returned by insert_one() or insert_many(). Another is converting every ObjectId to a string immediately and then forgetting that later queries may expect an ObjectId again. Developers are also sometimes surprised that the original document dictionary gets an _id added to it when one was not provided explicitly.

Summary

  • Use result.inserted_id after insert_one().
  • Use result.inserted_ids after insert_many().
  • PyMongo also adds _id to the original document object if it was missing.
  • Custom _id values are allowed as long as they are unique.
  • Keep the returned value as an ObjectId unless you specifically need a string form.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.