Skip to main content

mongo-orm

A MongoDB ORM for Python

Installation

pip install mongo-entity-orm

or

uv add mongo-entity-orm

Configuration

Set the following environment variables before using the ORM:

Variable Description
MONGODB_URI MongoDB connection string
MONGO_DATABASE_NAME Name of the database

Usage

Defining an Entity

Use the @entity decorator to map a class to a MongoDB collection. Your class should inherit from BaseEntity.

from mongo_orm import BaseEntity, entity

@entity(collection_name="users")
class User(BaseEntity):
    name: str
    email: str

Every entity automatically has an id field (UUID string) and a tenant_id field (defaults to "-").

CRUD Operations

All operations are available in both async (a-prefixed) and sync variants.

Get by ID

# async
user = await User.aget(id=user_id, tenant_id=tenant_id)

# sync
user = User.get(id=user_id, tenant_id=tenant_id)

Pass raise_not_found=True to raise an exception instead of returning None when the entity is not found.

Save

user = User(name="Alice", email="alice@example.com", tenant_id="acme")

# async
await user.asave()

# sync
user.save()

save() / asave() performs an upsert based on id, so it works for both creating and updating.

Update fields

# Update in-memory only
user.update(name="Bob")

# Update and immediately save (async)
await user.aupdate(name="Bob", auto_save=True)

# Update and immediately save (sync)
user.update(name="Bob", auto_save=True)

Delete

# Delete an entity instance
user.delete()

# Delete by ID
User.delete_by_id(id=user_id, tenant_id=tenant_id)

Pass ignore_not_found=True to suppress an exception when the entity does not exist.

Querying

Find (filter)

filter accepts a standard MongoDB query dict.

# async
users = await User.afind(tenant_id=tenant_id, filter={"name": "Alice"})

# sync
users = User.find(tenant_id=tenant_id, filter={"name": "Alice"})

MongoDB operators work as expected:

users = await User.afind(
    tenant_id=tenant_id,
    filter={"name": {"$in": ["Alice", "Bob"]}, "email": {"$regex": "@example.com$"}},
)

Use tenant_id="*" to query across all tenants.

Pagination

users = await User.afind(tenant_id=tenant_id, filter={}, skip=0, limit=20)

Sorting

# Ascending
users = await User.afind(tenant_id=tenant_id, order_by="name")

# Descending (prefix with "-")
users = await User.afind(tenant_id=tenant_id, order_by="-name")

# Multiple sort fields
users = await User.afind(tenant_id=tenant_id, order_by=["-created_at", "name"])

Find first

user = await User.afind_first(tenant_id=tenant_id, filter={"email": "alice@example.com"})

Returns None if no match is found.

Count

# async
total = await User.acount(tenant_id=tenant_id, filter={"name": "Alice"})

# sync
total = User.count(tenant_id=tenant_id, filter={"name": "Alice"})

Scroll pages (batch iteration)

# async
async for page in User.ascroll_pages(tenant_id=tenant_id, page_size=50):
    for user in page:
        ...

# sync
for page in User.scroll_pages(tenant_id=tenant_id, page_size=50):
    for user in page:
        ...

Bulk save

await User.bulk_save([user1, user2, user3])

Index Management

Define indexes on the entity class using __indexes__:

@entity(collection_name="users")
class User(BaseEntity):
    name: str
    email: str

    __indexes__ = [
        {"keys": [("email", 1)], "unique": True},
        {"keys": [("name", 1)]},
        {"keys": [("tenant_id", 1), ("name", 1)]},
    ]

Index management is controlled by the MONGODB_INDEX_AUTOAPPLY environment variable:

Value Behaviour
never (default) No automatic index management
always Checks and applies indexes on every startup
auto-lock Applies indexes once; writes a hash to mongo-orm.lock and skips on subsequent startups

Manual application

from mongo_orm.utils import apply_all_indexes

# Respects MONGODB_INDEX_AUTOAPPLY
apply_all_indexes()

# Force a specific mode
apply_all_indexes(mode="always")

Development

# Install dependencies
poetry install

# Run tests
poetry run pytest

# Format code
poetry run black .
poetry run isort .

# Type checking
poetry run mypy src/

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mongo_entity_orm-0.3.0.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mongo_entity_orm-0.3.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file mongo_entity_orm-0.3.0.tar.gz.

File metadata

  • Download URL: mongo_entity_orm-0.3.0.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.1 CPython/3.13.3 Darwin/24.6.0

File hashes

Hashes for mongo_entity_orm-0.3.0.tar.gz
Algorithm Hash digest
SHA256 301a1e6b3b766048dd9126990bf290e5a2c4b3ab36cdcb45e41fc10d3dd6548e
MD5 d762091b49f63118ec51b376f7a0b9fc
BLAKE2b-256 d76eecf444eb52548498dd6a937a16d9372f36b8c310b696549e4726730a9fe6

See more details on using hashes here.

File details

Details for the file mongo_entity_orm-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: mongo_entity_orm-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.1 CPython/3.13.3 Darwin/24.6.0

File hashes

Hashes for mongo_entity_orm-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac36cebe28f3dde630d5d5e52aecbd2bde755c89a6a4d0fb3eb99712f055f6db
MD5 1547cfa0bddbcaa8bc53882a36819066
BLAKE2b-256 9f768134276d18f07a05e98e4c647740cefcad80eaa1371ad4879fe0e11cc6de

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page