3. Engine Setup

3.1 Engine Creation

The Engine constructor __init__ establishes the core MongoDB connection with centralized naming configuration. It accepts:

  • db: MongoDB database connection (Motor/AgnosticDatabase)

  • collection_name_format: Callable to generate collection names from model classes (default: class name)

  • link_name_format: Callable to generate field names for document relationships (default: field alias)

These format parameters allow consistent naming rules across all bound documents.

Example of engine creation:

motor = AsyncIOMotorClient("localhost")
engine = Engine(motor["butty_test"], link_name_format=lambda f: f.alias + "_id")

3.2 Document Binding

bind() registers document classes with the engine, processing:

  • Collection name resolution (via DocumentConfig or format callable)

  • Field injection and relationship pipeline setup

  • Duplicate binding prevention

The automatic document registry (populated via __init_subclass__) simplifies binding in complex applications by tracking document classes. When bind() is called without parameters, it uses all registered documents. The registration is carefully filtered to exclude:

  • Classes with registry=False explicit override

  • Abstract base classes (ABC)

  • Generic type definitions (containing ‘[‘)

  • Pydantic internal models (pydantic.main)

This filtering is necessary because __init_subclass__ triggers during various Pydantic setup operations, not just actual document class definitions. The registry system provides convenience while preventing unwanted automatic binding of support classes.

unbind() removes all document associations, clearing both explicitly bound documents and registry-tracked classes while maintaining the underlying collections.

Example of document binding:

engine.bind()  # binds all registered documents
engine.bind(User, Department)  # binds only User and Department

3.3 Engine Initialization

The init() method finalizes engine setup by creating all configured database indexes.

Example of engine initialization:

async def main():
    await engine.init()