ODMantic
raw JSON → 1.1.0 verified Fri May 01 auth: no python
ODMantic is an async ODM (Object Document Mapper) for MongoDB, based on Pydantic and Motor. It leverages Python type hints to define models and provides a clean asynchronous API. Current version is 1.1.0, with active development and quarterly releases.
pip install odmantic Common errors
error AttributeError: 'AIOEngine' object has no attribute 'save' ↓
cause In older versions (<0.7), 'save' was a method on the Engine instance. After refactoring, it's still a method, but the error may occur if a typo or using a wrong object.
fix
Ensure you're using the AIOEngine correctly:
await engine.save(instance). Verify you have installed ODMantic >=0.7. error pydantic.errors.PydanticUserError: Cannot use `Field` from pydantic inside an ODMantic model ↓
cause Using `from pydantic import Field` instead of `from odmantic import Field`.
fix
Change the import to:
from odmantic import Field error TypeError: 'coroutine' object does not support item assignment ↓
cause Forgetting to await an async engine call (e.g., `engine.find_one(...)` returns a coroutine, not the result).
fix
Add
await before the engine call: player = await engine.find_one(...) Warnings
breaking ODMantic 1.0.0 dropped support for Pydantic v1 and Python 3.7. Models defined with Pydantic v1 syntax will break. ↓
fix Upgrade models to Pydantic v2 syntax (e.g., use `Field` from odmantic, update validators).
gotcha Do not mix ODMantic's `Field` with Pydantic's `Field`. Using `from pydantic import Field` inside an ODMantic model can cause validation issues. ↓
fix Always import Field from odmantic: `from odmantic import Field`.
gotcha ODMantic models are async-only. Calling `save()` without `await` will not persist data and may return a coroutine. ↓
fix Always use `await` with engine methods like `save`, `find`, `find_one`, `delete`, etc.
Imports
- Model wrong
from pydantic import BaseModelcorrectfrom odmantic import Model - Field wrong
from pydantic import Fieldcorrectfrom odmantic import Field - ObjectId wrong
from bson import ObjectIdcorrectfrom odmantic import ObjectId
Quickstart
import asyncio
from odmantic import AIOEngine, Model, Field
from motor.motor_asyncio import AsyncIOMotorClient
class Player(Model):
name: str
level: int = Field(default=1)
async def run():
client = AsyncIOMotorClient(os.environ.get('MONGODB_URI', 'mongodb://localhost:27017'))
engine = AIOEngine(motor_client=client, database='test')
player = Player(name='Alice', level=5)
await engine.save(player)
print(f"Saved player with id: {player.id}")
found = await engine.find_one(Player, Player.name == 'Alice')
print(found)
client.close()
asyncio.run(run())