Describe the bug
When parent documents are implemented and shared among multiple documents, if all documents are initialized, the _link_fields variable of the various documents gets improperly initialized and documents gets contaminated with links from other documents. This has been ovserved in all latest versions.
To Reproduce
import pytest
from beanie import Document, Link
class RootDocument(Document):
name: str
link_root: Link[Document]
class ADocument(RootDocument):
surname: str
link_a: Link[Document]
class Settings:
name = 'B'
class BDocument(RootDocument):
email: str
link_b: Link[Document]
class Settings:
name = 'B'
# >>> FIX
DOCS = [
RootDocument,
ADocument,
BDocument,
]
@pytest.fixture(autouse=True)
async def configure():
# todo : DRY
import motor.motor_asyncio
from beanie import init_beanie
from api.seed.env import Environ
client = motor.motor_asyncio.AsyncIOMotorClient(Environ.MONGO_URL, tz_aware=True)
db = client.get_default_database()
await init_beanie(database=db, document_models=DOCS)
@pytest.fixture(autouse=True, scope='function')
async def clear(configure):
for doc in DOCS:
await doc.delete_all()
# >>> TEST
async def test_query_composition():
SYS = {'id', 'revision_id'}
# Simple fields are initialized using the pydantic __fields__ internal property
# such fields are properly isolated when multi inheritance is involved.
assert set(RootDocument.__fields__.keys()) == SYS | {'name', 'link_root'}
assert set(ADocument.__fields__.keys()) == SYS | {'name', 'link_root', 'surname', 'link_a'}
assert set(BDocument.__fields__.keys()) == SYS | {'name', 'link_root', 'email', 'link_b'}
# Where Document.init_fields() has a bug that prevents proper link inheritance when parent
# documents are initialized. Furthermore, some-why BDocument._link_fields are not deterministic
assert set(RootDocument._link_fields.keys()) == {'link_root'}
assert set(ADocument._link_fields.keys()) == {'link_root', 'link_a'}
assert set(BDocument._link_fields.keys()) == {'link_root', 'link_b'}
Expected behavior
Each document should know/use only own and inherited links.
Additional context
We have implemented different "base documents" that gets then mixed and matched to compose new documents, this alow us to structure documents and better isolate functionalities. When beanie is initialized we initialize all of them, to better power queries.
Here RootDocument is not a real document as it lacks of any collection name, but is shared among multiple documents. This document is initialized to trigger the internal field initialization process and allow us to implement reusable queries that use directly the root document field RootDocument.name == 'beanie', or implement root functions:
Describe the bug When parent documents are implemented and shared among multiple documents, if all documents are initialized, the
_link_fields
variable of the various documents gets improperly initialized and documents gets contaminated with links from other documents. This has been ovserved in all latest versions.To Reproduce
Expected behavior Each document should know/use only own and inherited links.
Additional context We have implemented different "base documents" that gets then mixed and matched to compose new documents, this alow us to structure documents and better isolate functionalities. When beanie is initialized we initialize all of them, to better power queries.
Here
RootDocument
is not a real document as it lacks of any collection name, but is shared among multiple documents. This document is initialized to trigger the internal field initialization process and allow us to implement reusable queries that use directly the root document fieldRootDocument.name == 'beanie'
, or implement root functions:Our current fixes are:
But why is this check performed?