Skip to content

[BUG] Link DBRefs do not preserve extra attributes when calling document.model_dump() #1041

@MrEarle

Description

@MrEarle

Describe the bug
When dumping a model with links, the corresponding DBRef dicts don't keep extra attributes.

To Reproduce

class User(Document):
    email: str


class ToDo(Document):
    user: Link[User]


async def main():
    client = AsyncIOMotorClient(db_uri)
    await init_beanie(
        database=client.get_database("test"),
        document_models=[User, ToDo],
    )

    user = await User(email="test@example.com").create()

    user_db_ref = DBRef("user", user.id, _extra={"email": user.email})

    todo = await ToDo(user=user_db_ref).create()

    print(todo.model_dump()["user"])  # Does not print the email field

Expected behavior
A clear and concise description of what you expected to happen.

I would expect that the serialization of the DBRef contains the extra fields it contains. This helps in having an extended reference pattern.

Additional context

Playing around with beanie's implementation, I got it working by modifying the to_dict method of Link:

    def to_dict(self):
        extra = {k: v for k,v in self.ref.as_doc().items() if k not in {"$ref", "$id", "$db"}}
        return {**extra, "id": str(self.ref.id), "collection": self.ref.collection}

Edit: This would probably change how to do serialization with Pydantic. For example, in build_validation for Pydantic V2, if isinstance(v, dict) and v.keys() == {"id", "collection"} is used to detect if the dict is a DBRef. Given that keys can now contain more items, the strict equality would no longer hold.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions