BeanieODM / beanie

Asynchronous Python ODM for MongoDB
http://beanie-odm.dev/
Apache License 2.0
2.06k stars 217 forks source link

[BUG] Writerules.WRITE only works for first level fields #993

Open HasanYldz opened 3 months ago

HasanYldz commented 3 months ago

Describe the bug Writerules.WRITE only works for first level fields . links on sub fields are saved as documents not relations.

To Reproduce


class ServiceRelationship(BaseModel):
    relationship_type: str
    service: Optional[list[Link[Service]]] = None  # noqa

class Service(Document):
    name: str
    supporting_service: Optional[list[Link[Service]]] = None
    service_relationship: Optional[list[ServiceRelationship]] = None
    class Settings:
        keep_nulls = False

service_dict = {
    "name": "service",
    "service_relationship": [
        {
            "relationship_type": "relation",
            "service": [
                {
                    "name": "related service"
                }
            ]
        }
    ],
    "supporting_service": [
        {
            "name": "supporting service"
        }
    ]
}
service = Service(**service_dict)
await service.insert(link_rule=WriteRules.WRITE)

Expected behavior Writerules.WRITE should work for subfields

Additional context Created document: image

bonya commented 2 months ago

Same here. Link in nested document is not working. beanie==1.26.0

async def test_link_from_nested_document(m):
    import json
    from pydantic import BaseModel
    from typing import List
    from beanie import Document, Link, WriteRules, init_beanie

    class User(Document):
        class Settings:
            name = "users"
        name: str

    class Role(Document):
        class Settings:
            name = "roles"
        name: str

    class Permission(BaseModel):
        user: Link[User]
        role: Link[Role]

    class Project(Document):
        class Settings:
            name = "projects"
        user: Link[User]
        permission: Permission
        permissions: List[Permission]

    await init_beanie(database=m, document_models=[User, Role, Project])

    user = await User(name="user").insert()
    role = await Role(name="role").insert()

    await Project(
        user=user,
        permission=Permission(user=user, role=role),
        permissions=[Permission(user=user, role=role)]
    ).insert(link_rule=WriteRules.WRITE)

    assert await User.count() == 1
    assert await Role.count() == 1
    assert await Project.count() == 1

    print(json.dumps(await m.projects.find_one(), indent=4, default=str))

Result

{
    "_id": "66c0f05f3497867388f6c546",
    "user": "DBRef('users', ObjectId('66c0f05f3497867388f6c544'))",
    "permission": {
        "user": {
            "_id": "66c0f05f3497867388f6c544",
            "revision_id": null,
            "name": "user"
        },
        "role": {
            "_id": "66c0f05f3497867388f6c545",
            "revision_id": null,
            "name": "role"
        }
    },
    "permissions": [
        {
            "user": {
                "_id": "66c0f05f3497867388f6c544",
                "revision_id": null,
                "name": "user"
            },
            "role": {
                "_id": "66c0f05f3497867388f6c545",
                "revision_id": null,
                "name": "role"
            }
        }
    ]
}

Expected result:

{
    "_id": "66c0f05f3497867388f6c546",
    "user": "DBRef('users', ObjectId('66c0f05f3497867388f6c544'))",
    "permission": {
        "user": "DBRef('users', ObjectId('66c0f05f3497867388f6c544'))",
        "role": "DBRef('users', ObjectId('66c0f05f3497867388f6c545'))"
    },
    "permissions": [
        {
            "user": "DBRef('users', ObjectId('66c0f05f3497867388f6c544'))",
            "role": "DBRef('users', ObjectId('66c0f05f3497867388f6c545'))"
        }
    ]
}
github-actions[bot] commented 1 month ago

This issue is stale because it has been open 30 days with no activity.

github-actions[bot] commented 1 month ago

This issue was closed because it has been stalled for 14 days with no activity.

staticxterm commented 1 month ago

Hi, this is mentioned in the documentation: Only top-level fields are fully supported for now. https://beanie-odm.dev/tutorial/relations/ I can reopen this as a feature request.