Search code examples
pythonmongodbfastapiodm

beanie.exceptions.CollectionWasNotInitialized error


I'm new to the Beanie library which is

an asynchronous Python object-document mapper (ODM) for MongoDB. Data models are based on Pydantic.

I was trying this library with fastAPI framework, and made an ODM for some document, let's say it's name is SomeClass and then tried to insert some data in the db using this ODM.
Here's the code for ODM and the method to create a document (insomeClass.py):

from beanie import Document
from pydantic import Field, BaseModel
 
class SomeClassDto(BaseModel):
    """
    A Class for Data Transferring.
    """
    name: str = Field(max_length=maxsize, min_length=1)


class SomeClassDao:
    """
    This is a class which holds the 'SomeClass' class (inherited from Beanie Document),
    and also, the methods which use the 'SomeClass'  class.
    """
    class SomeClass(Document):
        name: str = Field(max_length=20, min_length=1)
        

    @classmethod
    async def create_some_class(cls, body: SomeClassDto):
        some_class = cls.SomeClass(**body.dict())
        return await cls.SomeClass.insert_one(some_class)

I've used and called the create_some_class function, but it throwed this error:
beanie.exceptions.CollectionWasNotInitialized

However the error is self-explanatory but I didn't understand at first, and couldn't find any relatable question about my problem in SO, so I decided to post this question and answer it, for the sake of future.


Solution

  • As the error tells us, we should first Initialize the collection.
    We should initialize the collection via the init_beanie. I’ve used this function like this (in databse.py):

    from beanie import init_beanie
    import motor.motor_asyncio
    from someClass import SomeClassDao
    
    async def init_db(cls):
                MONGO_DB_DATABASE_NAME = "SomeDBName"
                MOTOR_CLIENT = motor.motor_asyncio.AsyncIOMotorClient()
                DATABASE = MOTOR_CLIENT[MONGO_DB_DATABASE_NAME]
                document_models = [SomeClassDao.SomeClass,]
                await init_beanie(database=cls.DATABASE, document_models=document_models)
    

    And then we should use this function at the startup of the app, so we use it like this (in main.py):

    from fastapi import FastAPI
    from database import init_db
    
    app = FastAPI()
    @app.on_event("startup")
    async def start_db():
        await init_db()
    
    • Then after creating the init_beanie function and adding the document we want to use to the document_models, it worked without error.

    Hope this helps.