BeanieODM / beanie

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

[BUG] alias are ignored in model_dump for the documents in Link #705

Closed RobertoBochet closed 7 months ago

RobertoBochet commented 11 months ago

Describe the bug Hi, another bug related to migration to pydantic v2. In the case you have a Document with a field of type Link to another Document, when you try to perform a model_dump of the root Document requiring the use of the alias this directive is applied only for the root Document

To Reproduce

class C(Document):
    a: Annotated[str, Field(alis="_a")] = 'f'

class D(Document):
    c: Link[C]

c = C()
await c.save()
c = await C.get(c.id)
d = D(c=c)
await d.save()
d = await D.get(d.id)
await d.fetch_all_links()
d.model_dump(by_alias=True)

This results in

{'_id': '6503b090ba1e38cf02b18fc1', 'c': {'id': '6503b090ba1e38cf02b18fc0', 'a': 'f'}}

Expected behavior The example above should return

{'_id': '6503b090ba1e38cf02b18fc1', 'c': {'_id': '6503b090ba1e38cf02b18fc0', '_a': 'f'}}

Additional context

python=="3.11.5"
pydantic=="2.3.0"
beanie=="1.22.1"

In FastAPI this bug prevents the use of Link in the response models

Thank so much for your work

roman-right commented 11 months ago

Hi! Thank you for the catch. I'll check and fix it this/next week.

roman-right commented 9 months ago

Hi @RobertoBochet , Sorry for the late reply. It looks like you have a typo in word "alias". You use "alis"

Here is fixed version. It looks like it works. Please try:

import asyncio
from typing import Annotated

from motor.motor_asyncio import AsyncIOMotorClient
from pydantic import Field

from beanie import init_beanie, Document, Link

class C(Document):
    a: Annotated[str, Field(alias="_a")] = 'f'

class D(Document):
    c: Link[C]

async def main():
    client = AsyncIOMotorClient("mongodb://beanie:beanie@localhost:27017")
    db = client.beanie_test
    await init_beanie(database=db, document_models=[C, D])

    c = C()
    await c.save()
    c = await C.get(c.id)
    d = D(c=c)
    await d.save()
    d = await D.get(d.id)
    await d.fetch_all_links()
    print(d)
    print(d.c.a)
    print(d.model_dump(by_alias=True))

asyncio.run(main())
github-actions[bot] commented 8 months ago

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

github-actions[bot] commented 7 months ago

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