-
Notifications
You must be signed in to change notification settings - Fork 219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Projection model not working in aggregation #1017
Comments
This issue is stale because it has been open 30 days with no activity. |
Hi, I am unable to reproduce this on Python3.13, Beanie 1.27.0 (or even 1.26.0) and Pydantic 2.9.2 (or 1.10.18). import asyncio
from beanie import Document, init_beanie
from motor.motor_asyncio import AsyncIOMotorClient
from pydantic import BaseModel, ConfigDict, Field
class Doc(Document):
id: str = Field(
...,
alias="_id",
)
field_a: str
field_b: str
class Model(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
id: str = Field(
...,
alias="_id",
)
field_b: str
async def main():
client = AsyncIOMotorClient("mongodb://localhost:27017")
database = client["test-db"]
await init_beanie(database, document_models=[Doc])
# Run DB queries now.
doc = Doc(id="1", field_a="a", field_b="b")
result = await doc.save()
print(result)
results = (
await Doc.find()
.aggregate(aggregation_pipeline=[], projection_model=Model)
.to_list()
)
print(results)
if __name__ == "__main__":
asyncio.run(main()) Output: id='1' revision_id=None field_a='a' field_b='b'
[Model(id='1', field_b='b')] |
I feel like I had this issue once when using pydantic v1, seems slightly familiar... don't quote me on that though |
Hey, thanks for the response. I will try to provide a better reproduction. |
It's bit of a "weird" case, but below is the full reproduction. Here is the document example: {
"_id": "my_id",
"field_list": [
{
"id": "id_1",
"field_a": "a",
"field_b": "b"
},
{
"id": "id_2",
"field_a": "a",
"field_b": "b"
}
]
} The aim is to get as result the nested object (projected to exclude {
"id": "id_1",
"field_a": "a"
} Here is the code to reproduce. Notice how the import asyncio
from beanie import Document, init_beanie
from motor.motor_asyncio import AsyncIOMotorClient
from pydantic import BaseModel, Field, ConfigDict
class ProjectionModel(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
id: str = Field(
...,
alias="_id",
)
field_a: str
class Model(BaseModel):
id: str
field_a: str
field_b: str
class Doc(Document):
id: str = Field(
...,
alias="_id",
)
field_list: list[Model]
async def query(list_item_id: str):
results = (
await Doc.find()
.aggregate(
aggregation_pipeline=[
{
"$unwind": "$field_list",
},
{
"$match": {
"field_list.id": list_item_id,
},
},
{
"$replaceRoot": {
"newRoot": "$field_list",
}
},
],
projection_model=ProjectionModel,
)
.to_list()
)
return results
async def main():
client = AsyncIOMotorClient("mongodb://localhost:27017")
await init_beanie(
database=client.test_db,
document_models=[Doc],
)
# Run DB queries now.
doc = Doc(
id="my_id",
field_list=[
Model(
id="id_1",
field_a="a",
field_b="b",
),
Model(
id="id_2",
field_a="a",
field_b="b",
),
],
)
result = await doc.save()
print(result)
try:
results = await query(list_item_id="id_1")
print(results)
finally:
# pass
await doc.delete()
if __name__ == "__main__":
asyncio.run(main()) |
Describe the bug
When I provide a
projection_model
toFindMany.aggregate()
, that has theid
property with analias="_id"
it fails to project with the following errorThis happens even if I set
populate_by_name=True
on the Pydantic model.To Reproduce
Expected behavior
This should work. I should not have to manually project each result from the query, like
[Model(**res) for res in results]
The text was updated successfully, but these errors were encountered: