Modern async MongoDB ORM for Python with Pydantic integration.
Project description
MongoDB ORM
A modern, async MongoDB Object-Relational Mapping library for Python, built on top of Motor and Pydantic.
About This Project
This is an improved and enhanced version of the original mongodb_orm project. This fork includes significant improvements, bug fixes, and new features to provide a more robust and user-friendly MongoDB ORM experience.
Features
- ✨ Fully Async: Built from the ground up with async/await support
- 🔒 Type Safe: Leverages Pydantic for robust data validation and type hints
- 🚀 High Performance: Uses Motor for efficient async MongoDB operations
- 🛡️ Error Handling: Comprehensive exception handling with custom exception types
- 🔧 Flexible Configuration: Environment-based configuration with sensible defaults
- 📊 Connection Management: Automatic connection pooling and cleanup
- 🗃️ Rich Query API: Intuitive methods for CRUD operations and aggregations
- 📈 Indexing Support: Easy index creation and management
- 🧪 Testing Utilities: Built-in utilities for testing and development
Installation
pip install br_mongodb_orm
For development dependencies:
pip install br_mongodb_orm[dev]
Quick Start
1. Environment Setup
Set your MongoDB connection details:
export MONGO_URI="mongodb://localhost:27017"
export MONGO_DATABASE="my_app_db"
2. Define Your Models
import asyncio
from datetime import datetime
from typing import Optional
from br_mongodb_orm import BaseModel, register_all_models
# Simple models - no Meta class required!
class User(BaseModel):
name: str
email: str
age: Optional[int] = None
is_active: bool = True
# created_at and updated_at are automatically added
class BlogPost(BaseModel):
title: str
content: str
author_id: int
tags: list[str] = []
published: bool = False
# Collection name will be "blog_post" automatically
# Optional: Use Meta class only if you need custom settings
class CustomModel(BaseModel):
name: str
class Meta:
collection_name = "my_custom_collection" # Override default
auto_create_indexes = False # Disable auto-indexing
# Register all models
async def setup_models():
await register_all_models(__name__)
asyncio.run(setup_models())
Key Benefits:
- ✅ No Meta class required for basic usage
- ✅ Auto-generated collection names (User → "user", BlogPost → "blog_post")
- ✅ Automatic index creation enabled by default
- ✅ Smart naming conversion (CamelCase → snake_case)
3. Basic Operations
async def main():
# Create a new user (collection "user" created automatically)
user = await User.create(
name="John Doe",
email="john@example.com",
age=30
)
print(f"Created user: {user}")
# Get user by ID
found_user = await User.get_by_id(user.id)
# Update user
found_user.age = 31
await found_user.save()
# Query users (returns async cursor for memory efficiency)
async for user in User.filter(is_active=True):
print(f"Active user: {user.name}")
# Or convert to list if needed
active_users = await User.filter(is_active=True).to_list()
# Create a blog post (collection "blog_post" created automatically)
post = await BlogPost.create(
title="My First Post",
content="This is the content of my first post.",
author_id=user.id,
tags=["introduction", "first-post"],
published=True
)
# Get posts by author (memory-efficient iteration)
async for post in BlogPost.filter(author_id=user.id):
print(f"Post: {post.title}")
# Or get as list
user_posts = await BlogPost.filter(author_id=user.id).to_list()
# Delete post
await post.delete()
asyncio.run(main())
What happens automatically:
- ✅ Collections are created with smart names
- ✅ Indexes are created on id, created_at, updated_at fields
- ✅ Timestamps are managed automatically
- ✅ Data validation with Pydantic
Advanced Usage
Automatic Collection Naming
The ORM automatically converts your class names to collection names using snake_case:
class User(BaseModel): # → collection: "user"
pass
class BlogPost(BaseModel): # → collection: "blog_post"
pass
class ShoppingCart(BaseModel): # → collection: "shopping_cart"
pass
class APIKey(BaseModel): # → collection: "api_key"
pass
class XMLDocument(BaseModel): # → collection: "xml_document"
pass
Custom Configuration
Only use Meta class when you need to override defaults:
class User(BaseModel):
name: str
email: str
class Meta:
collection_name = "users" # Override auto-generated name
auto_create_indexes = False # Disable automatic indexing
strict_mode = True # Enable strict validation
use_auto_id = True # Use auto-increment IDs
id_field = "user_id" # Custom ID field name
Requirements
- Python 3.8+
- motor>=3.5.1
- pydantic>=2.8.2
- pymongo>=4.0.0
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file br_mongodb_orm-2.0.2.tar.gz.
File metadata
- Download URL: br_mongodb_orm-2.0.2.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af4590874a64f3253e5ec038b3749577ce783f0c1a77cfa4ac81460ba90dcf3e
|
|
| MD5 |
594094fb61638b2a16985b8b0be4b92b
|
|
| BLAKE2b-256 |
fc0d6075f4a2a988e5214d976010e60ec58503c1a77ef79a7956ef9acdaf6bdb
|
File details
Details for the file br_mongodb_orm-2.0.2-py3-none-any.whl.
File metadata
- Download URL: br_mongodb_orm-2.0.2-py3-none-any.whl
- Upload date:
- Size: 17.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d654f8636bb0a9806b66983139f774839b523c9aabacf4bdd018274d774c529
|
|
| MD5 |
183962efc0203199bf7208359e3ac14e
|
|
| BLAKE2b-256 |
385f652708460ddb01d34c1299ca14b6c71fd83a1c8c3d6368f7346b48d1faf1
|