Skip to content

[BUG] Calling init_beanie twice with different models results in object ID permanently set to _id #1228

@sstraub-hmmc

Description

@sstraub-hmmc

Describe the bug

When a custom base class is used which inherits from beanie.Document, the base class gets modified when init_beanie() is called. This leads to bugs later on if init_beanie() is called again with a different model that inherits from the same class.

Usually I try to avoid calling init_beanie() multiple times, but I was writing a tutorial in a Python notebook and there I ran into this issue...

To Reproduce

from beanie import Document, init_beanie
from pymongo import AsyncMongoClient


async def test_inheritance_bug():
    client = AsyncMongoClient("mongodb://root:secret@localhost:27017")
    database = client.get_database("test")

    class A(Document):
        a: str | None = None

    await init_beanie(database=database, document_models=[A])
    a = A(a="foo")
    assert a.id is None

    class B(Document):
        b: str | None = None

    await init_beanie(database=database, document_models=[B])
    b = B(b="bar")
    assert b.id is None

    class MyDocument(Document):
        pass

    class A2(MyDocument):
        a: str | None = None

    await init_beanie(database=database, document_models=[A2])
    a2 = A2(a="foo")
    assert a2.id is None

    class B2(MyDocument):
        b: str | None = None

    await init_beanie(database=database, document_models=[B2])
    b2 = B2(b="bar")
    # THIS FAILS: B2(id='_id', revision_id='revision_id', b='bar')
    assert b2.id is None

Expected behavior

It should be possible to call init_beanie() multiple times during the runtime of an application without things breaking (even if it's not best practice). In this case, things are breaking

Additional context

When init_beanie is called with MyDocument for the first time, two new fields are assigned to the MyDocument type: id: ExpressionField = '_id' and revision_id: ExpressionField = 'revision_id'. This causes subsequent failures, since now every new instance of the model has '_id' as object id, which is invalid.

The issue does not come up if you declare B2 before you call init_beanie, even if you don't add B2 to the document_models. In any case, this is not a viable workaround for me, since I need to be able to declare new models later on in my jupyter notebook.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions