We use Motor to connect FastAPI with MongoDB because Motor lets us talk to the database without stopping our app. It works smoothly with FastAPI's async style.
MongoDB integration with Motor in FastAPI
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
FastAPI
from motor.motor_asyncio import AsyncIOMotorClient client = AsyncIOMotorClient('mongodb://localhost:27017') db = client['database_name'] collection = db['collection_name'] # Example async function to insert a document async def insert_document(doc): result = await collection.insert_one(doc) return result.inserted_id
Use AsyncIOMotorClient to create a connection that works with async code.
Always use await when calling Motor methods to avoid blocking.
Examples
FastAPI
client = AsyncIOMotorClient('mongodb://localhost:27017') db = client['testdb'] collection = db['users']
FastAPI
async def add_user(user_data): result = await collection.insert_one(user_data) return result.inserted_id
FastAPI
async def find_user(name): user = await collection.find_one({'name': name}) return user
Sample Program
This FastAPI app connects to MongoDB using Motor. It has two routes: one to add an item and one to get an item by name.
FastAPI
from fastapi import FastAPI from motor.motor_asyncio import AsyncIOMotorClient app = FastAPI() client = AsyncIOMotorClient('mongodb://localhost:27017') db = client['sampledb'] collection = db['items'] @app.post('/items/') async def create_item(item: dict): inserted_id = await collection.insert_one(item) return {'inserted_id': str(inserted_id.inserted_id)} @app.get('/items/{name}') async def read_item(name: str): item = await collection.find_one({'name': name}) if item: item['_id'] = str(item['_id']) return item return {'error': 'Item not found'}
Important Notes
Motor is an async driver, so always use async functions and await Motor calls.
Convert MongoDB ObjectId to string before returning JSON to avoid errors.
Make sure MongoDB server is running before connecting.
Summary
Motor lets FastAPI talk to MongoDB without waiting or blocking.
Use async functions and await Motor calls to keep your app fast.
Remember to convert ObjectId to string when sending data back to users.
Practice
1. What is the main benefit of using Motor with FastAPI for MongoDB operations?
easy
Solution
Step 1: Understand Motor's role in FastAPI
Motor is an async driver for MongoDB, enabling non-blocking calls in FastAPI apps.Step 2: Identify the main benefit
Non-blocking calls keep the app responsive and fast by not waiting for DB operations.Final Answer:
It allows asynchronous, non-blocking database calls. -> Option CQuick Check:
Motor = async, non-blocking calls [OK]
Hint: Motor means async MongoDB calls in FastAPI [OK]
Common Mistakes:
- Thinking Motor provides UI tools
- Assuming Motor auto-converts ObjectId
- Confusing Motor with FastAPI routing
2. Which of the following is the correct way to define a Motor client in FastAPI?
easy
Solution
Step 1: Recall Motor client syntax
The Motor async client is created using motor.motor_asyncio.AsyncIOMotorClient with the MongoDB URI.Step 2: Check each option
Only client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017') uses the correct class and URI format for Motor.Final Answer:
client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017') -> Option AQuick Check:
Motor client = AsyncIOMotorClient [OK]
Hint: Use AsyncIOMotorClient from motor.motor_asyncio [OK]
Common Mistakes:
- Using MotorClient instead of AsyncIOMotorClient
- Omitting 'motor.motor_asyncio' prefix
- Using synchronous MongoClient
3. Given this FastAPI async function using Motor, what will be the output?
async def get_user(db, user_id):
user = await db.users.find_one({"_id": user_id})
return str(user["_id"])medium
Solution
Step 1: Analyze the async function
The function awaits a find_one query by _id and then converts the _id field to string.Step 2: Understand the output
It returns the string form of the ObjectId, not the whole document or None.Final Answer:
Returns the string representation of the user's ObjectId. -> Option BQuick Check:
str(ObjectId) = string id [OK]
Hint: str() converts ObjectId to string safely [OK]
Common Mistakes:
- Expecting full user dict as output
- Thinking ObjectId can't be stringified
- Assuming None is returned if not found
4. Identify the error in this Motor usage inside FastAPI:
async def fetch_items(db):
items = db.items.find()
return await items.to_list(length=100)medium
Solution
Step 1: Understand Motor's find() behavior
Motor's find() returns an async cursor immediately; no await needed here.Step 2: Check to_list() usage
to_list() is a coroutine and must be awaited to get the list of documents.Final Answer:
No error; code is correct. -> Option DQuick Check:
find() no await, to_list() await [OK]
Hint: Await to_list(), not find() [OK]
Common Mistakes:
- Awaiting find() call incorrectly
- Not awaiting to_list() causing runtime error
- Confusing synchronous and async cursor methods
5. You want to return a list of users from MongoDB in FastAPI, but each user's
_id must be a string, not ObjectId. Which code snippet correctly does this?hard
Solution
Step 1: Fetch users as list of dicts
await db.users.find().to_list(100) returns list of user dicts with ObjectId _id fields.Step 2: Convert each user's _id to string
Use list comprehension to copy each dict and replace _id with str(u['_id']).Final Answer:
users = await db.users.find().to_list(100) return [{**u, '_id': str(u['_id'])} for u in users] -> Option AQuick Check:
Convert ObjectId to string per user [OK]
Hint: Use dict unpacking and str() on _id in list comprehension [OK]
Common Mistakes:
- Returning ObjectId directly without conversion
- Trying to convert whole user dict to string
- Filtering users instead of converting _id
