Skip to main content

Database functionality for Mindtrace

Project description

PyPI version License Downloads

Mindtrace Database

The Database module provides Mindtrace’s object-document mapping layer for MongoDB, Redis, Registry-backed storage, and unified multi-backend workflows.

Features

  • Unified ODM interface through UnifiedMindtraceODM
  • Backend-specific ODMs for MongoDB, Redis, and Registry-backed storage
  • Single-model and multi-model operation in the same API style
  • Sync and async access patterns across all supported backends
  • Unified document models that can target both MongoDB and Redis
  • Consistent exceptions such as DocumentNotFoundError and DuplicateInsertError

Quick Start

import asyncio

from pydantic import Field

from mindtrace.database import BackendType, UnifiedMindtraceDocument, UnifiedMindtraceODM


class User(UnifiedMindtraceDocument):
    name: str = Field(description="User name")
    email: str = Field(description="Email address")
    age: int = Field(ge=0)

    class Meta:
        collection_name = "users"
        global_key_prefix = "myapp"
        indexed_fields = ["email", "name"]
        unique_fields = ["email"]


async def main():
    db = UnifiedMindtraceODM(
        unified_model_cls=User,
        mongo_db_uri="mongodb://localhost:27017",
        mongo_db_name="myapp",
        redis_url="redis://localhost:6379",
        preferred_backend=BackendType.MONGO,
    )

    user = User(name="Alice", email="alice@example.com", age=30)
    inserted = await db.insert_async(user)
    fetched = await db.get_async(inserted.id)
    print(fetched)


asyncio.run(main())

In practice, the database module gives you a common way to define document models and CRUD workflows while choosing the backend that best fits your application.

Core Concepts

The package revolves around four main ODM styles:

  • UnifiedMindtraceODM — one API over MongoDB and/or Redis
  • MongoMindtraceODM — MongoDB-specific ODM built on Beanie
  • RedisMindtraceODM — Redis-specific ODM built on redis-om
  • RegistryMindtraceODM — Registry-backed ODM for simpler local or storage-backed document persistence

The package also provides matching document model bases:

  • UnifiedMindtraceDocument
  • MindtraceDocument
  • MindtraceRedisDocument

UnifiedMindtraceODM

UnifiedMindtraceODM is the recommended starting point when you want one API that can work across MongoDB and Redis.

Unified document model

from pydantic import Field

from mindtrace.database import UnifiedMindtraceDocument


class User(UnifiedMindtraceDocument):
    name: str = Field(description="User name")
    email: str = Field(description="Email")
    age: int = Field(ge=0)

    class Meta:
        collection_name = "users"
        global_key_prefix = "myapp"
        indexed_fields = ["email", "name"]
        unique_fields = ["email"]

Unified ODM setup

from mindtrace.database import BackendType, UnifiedMindtraceODM


db = UnifiedMindtraceODM(
    unified_model_cls=User,
    mongo_db_uri="mongodb://localhost:27017",
    mongo_db_name="myapp",
    redis_url="redis://localhost:6379",
    preferred_backend=BackendType.MONGO,
)

Common operations

# Async operations
inserted_user = await db.insert_async(User(name="Alice", email="alice@example.com", age=30))
retrieved_user = await db.get_async(inserted_user.id)
retrieved_user.age = 31
updated_user = await db.update_async(retrieved_user)
all_users = await db.all_async()
python_users = await db.find_async({"name": "Alice"})
# Sync operations
inserted_user = db.insert(User(name="Bob", email="bob@example.com", age=25))
retrieved_user = db.get(inserted_user.id)
retrieved_user.age = 26
updated_user = db.update(retrieved_user)
all_users = db.all()

Switching backends

db.switch_backend(BackendType.REDIS)
redis_user = db.insert(User(name="Carol", email="carol@example.com", age=28))

current_backend = db.get_current_backend_type()
print(current_backend)

Multi-model mode

All ODMs in this package support multi-model mode.

class Address(UnifiedMindtraceDocument):
    street: str
    city: str

    class Meta:
        collection_name = "addresses"
        global_key_prefix = "myapp"


db = UnifiedMindtraceODM(
    unified_models={"user": User, "address": Address},
    mongo_db_uri="mongodb://localhost:27017",
    mongo_db_name="myapp",
    redis_url="redis://localhost:6379",
)

address = await db.address.insert_async(Address(street="123 Main St", city="NYC"))
user = await db.user.insert_async(User(name="Alice", email="alice@example.com", age=30))
users = await db.user.all_async()

In multi-model mode, use attribute-based access like db.user.insert_async(...) rather than db.insert_async(...).

MongoMindtraceODM

Use MongoMindtraceODM when you want MongoDB-specific document models and Beanie features.

Mongo document model

from typing import Annotated

from beanie import Indexed

from mindtrace.database import MindtraceDocument


class MongoUser(MindtraceDocument):
    name: str
    email: Annotated[str, Indexed(unique=True)]
    age: int

    class Settings:
        name = "users"
        use_cache = False

Mongo ODM setup

from mindtrace.database import MongoMindtraceODM


db = MongoMindtraceODM(
    model_cls=MongoUser,
    db_uri="mongodb://localhost:27017",
    db_name="myapp",
)

Async-first behavior

MongoDB is natively async in this package.

inserted = await db.insert(MongoUser(name="Alice", email="alice@example.com", age=30))
fetched = await db.get(inserted.id)
results = await db.find(MongoUser.name == "Alice")

Sync wrappers

inserted = db.insert_sync(MongoUser(name="Bob", email="bob@example.com", age=25))
fetched = db.get_sync(inserted.id)
all_users = db.all_sync()

Linked documents

MongoDB supports Beanie Link fields.

from typing import Optional

from mindtrace.database import Link, MindtraceDocument, MongoMindtraceODM


class Address(MindtraceDocument):
    street: str
    city: str

    class Settings:
        name = "addresses"
        use_cache = False


class UserWithAddress(MindtraceDocument):
    name: str
    address: Optional[Link[Address]] = None

    class Settings:
        name = "users"
        use_cache = False


db = MongoMindtraceODM(
    models={"user": UserWithAddress, "address": Address},
    db_uri="mongodb://localhost:27017",
    db_name="myapp",
)

address = await db.address.insert(Address(street="123 Main St", city="NYC"))
user = await db.user.insert(UserWithAddress(name="Alice", address=address))
user_with_links = await db.user.get(user.id, fetch_links=True)

Aggregation

pipeline = [
    {"$match": {"age": {"$gte": 18}}},
    {"$group": {"_id": "$age", "count": {"$sum": 1}}},
]
results = await db.aggregate(pipeline)

RedisMindtraceODM

Use RedisMindtraceODM when you want Redis-backed JSON documents and indexed Redis OM queries.

Redis document model

from redis_om import Field

from mindtrace.database import MindtraceRedisDocument


class RedisUser(MindtraceRedisDocument):
    name: str = Field(index=True)
    email: str = Field(index=True)
    age: int = Field(index=True)

    class Meta:
        global_key_prefix = "myapp"

Redis ODM setup

from mindtrace.database import RedisMindtraceODM


db = RedisMindtraceODM(
    model_cls=RedisUser,
    redis_url="redis://localhost:6379",
)

Sync-first behavior

Redis is natively sync in this package.

inserted = db.insert(RedisUser(name="Alice", email="alice@example.com", age=30))
fetched = db.get(inserted.id)
results = db.find(RedisUser.age >= 18)
all_users = db.all()

Async wrappers

inserted = await db.insert_async(RedisUser(name="Bob", email="bob@example.com", age=25))
fetched = await db.get_async(inserted.id)
all_users = await db.all_async()

Notes on Redis IDs

Redis OM uses pk internally, but MindtraceRedisDocument exposes a consistent id property so code can treat MongoDB and Redis documents more similarly.

RegistryMindtraceODM

Use RegistryMindtraceODM when you want a simpler registry-backed ODM using Mindtrace’s Registry layer instead of a database server.

from pydantic import BaseModel

from mindtrace.database import RegistryMindtraceODM


class User(BaseModel):
    name: str
    email: str


db = RegistryMindtraceODM(model_cls=User)
inserted = db.insert(User(name="John Doe", email="john@example.com"))
retrieved = db.get(inserted.id)
retrieved.name = "John Smith"
updated = db.update(retrieved)
all_users = db.all()

This backend is useful when you want the ODM interface but prefer Registry-backed storage semantics.

Sync and Async Interfaces

All ODMs expose the same broad CRUD shape, but their native execution mode differs.

  • MongoMindtraceODM — native async, with sync wrappers
  • RedisMindtraceODM — native sync, with async wrappers
  • UnifiedMindtraceODM — routes to the active backend and adapts accordingly
  • RegistryMindtraceODM — sync-oriented

That means you can often keep the same mental model while fitting your application’s execution style.

Initialization

ODMs support automatic or explicit initialization.

from mindtrace.database import BackendType, InitMode, UnifiedMindtraceDocument, UnifiedMindtraceODM


db = UnifiedMindtraceODM(
    unified_model_cls=User,
    mongo_db_uri="mongodb://localhost:27017",
    mongo_db_name="myapp",
    redis_url="redis://localhost:6379",
    preferred_backend=BackendType.MONGO,
    auto_init=True,
    init_mode=InitMode.SYNC,
)

Init modes

  • InitMode.SYNC
  • InitMode.ASYNC

Defaults differ by backend:

  • MongoDB defaults to ASYNC
  • Redis defaults to SYNC
  • Registry is sync-oriented

Error Handling

The package provides a consistent exception surface across backends.

from mindtrace.database import DocumentNotFoundError, DuplicateInsertError


try:
    user = await db.get_async("missing-id")
except DocumentNotFoundError as e:
    print(f"Not found: {e}")

try:
    await db.insert_async(User(name="Alice", email="alice@example.com", age=30))
except DuplicateInsertError as e:
    print(f"Duplicate insert: {e}")

In multi-model mode, calling direct methods like db.insert(...) instead of db.user.insert(...) raises a ValueError to prevent ambiguity.

Installation

If you are working from the full Mindtrace repo:

$ git clone https://github.com/Mindtrace/mindtrace.git && cd mindtrace
$ uv sync --dev --all-extras

The database package depends on backend libraries such as Beanie, Motor, PyMongo, and Redis OM.

Examples

Related examples in the repo:

Testing

If you are working in the full Mindtrace repo, run tests for this module specifically:

$ git clone https://github.com/Mindtrace/mindtrace.git && cd mindtrace
$ uv sync --dev --all-extras
$ ds test: database
$ ds test: --unit database

If you want backend-specific integration coverage as well:

$ ds test: database --integration

Practical Notes and Caveats

  • UnifiedMindtraceODM only exposes the overlap of capabilities that make sense across MongoDB and Redis; backend-specific features still live on the backend-specific ODMs.
  • Multi-model mode changes the calling style: use attribute-based access like db.user.get(...).
  • MongoDB supports linked documents and aggregation; Redis does not provide the same feature set.
  • Redis and MongoDB differ in native execution style, so some methods are wrappers around the backend’s natural sync/async mode.
  • RegistryMindtraceODM is useful for simpler or storage-backed workflows, but its query capabilities are intentionally simpler than MongoDB or Redis.

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

mindtrace_database-0.13.0.tar.gz (49.0 kB view details)

Uploaded Source

Built Distribution

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

mindtrace_database-0.13.0-py3-none-any.whl (56.4 kB view details)

Uploaded Python 3

File details

Details for the file mindtrace_database-0.13.0.tar.gz.

File metadata

  • Download URL: mindtrace_database-0.13.0.tar.gz
  • Upload date:
  • Size: 49.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mindtrace_database-0.13.0.tar.gz
Algorithm Hash digest
SHA256 eb7ec0cfe1c1b57fff6540493de18641c3df8ef634def4d5837056a5905f06b0
MD5 4f73714de1f1022051c7905c8fc8d1ca
BLAKE2b-256 68f79bb6299aed74cac89a0b3113ca8baf1231e207bf550fa28f30dffa517ca9

See more details on using hashes here.

File details

Details for the file mindtrace_database-0.13.0-py3-none-any.whl.

File metadata

  • Download URL: mindtrace_database-0.13.0-py3-none-any.whl
  • Upload date:
  • Size: 56.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mindtrace_database-0.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a07213128e552ca1e05571d58a6182754414b953ae3a831211edc0a5823d912
MD5 310cfdfd6648d184169d83e590a9f796
BLAKE2b-256 1be308d3d37ef06700ec4818945b2dd3c9efe38946bbdce4034841de476acb6d

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