Skip to main content

A MongoDB ORM for Python

Project description

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

Project details


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.1.4.tar.gz (10.3 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.1.4-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mongo_entity_orm-0.1.4.tar.gz
  • Upload date:
  • Size: 10.3 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.1.4.tar.gz
Algorithm Hash digest
SHA256 b03af73185412ebc9bfce7134d937e9f78ab103f7b665de499a995bf55c8fa50
MD5 828844f493034e16c6824b8f241ae44d
BLAKE2b-256 08f4001d18d69f36dbef253952bd65bcbd988791717654137aed846cdb4f490e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: mongo_entity_orm-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 10.1 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.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 a0f689176cf0575a4357b52a2d373247205d0cf55e404005d4cd143efdab9d52
MD5 e18c2c36d7ba6b5632a961eac7afe647
BLAKE2b-256 323fcffa7077fd06195c51c7ffc5b05b7a761def4423cff411b881f3935b95b8

See more details on using hashes here.

Supported by

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