BeanieODM / beanie

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

[need help][question]fields not define in Document with loss #806

Closed hd10180 closed 7 months ago

hd10180 commented 7 months ago

Discussed in https://github.com/roman-right/beanie/discussions/765

Originally posted by **hd10180** November 2, 2023 when use beanie==1.13.0, fields not define in Document will loss when use save() method, here is a small case ``` import asyncio from datetime import datetime from beanie import Document, init_beanie from motor.motor_asyncio import AsyncIOMotorClient from pydantic import BaseModel, Field class Users(Document): name: str enabled: bool = True desc: str | None = None created: datetime = Field(default_factory=datetime.utcnow) class Settings: name = "users" use_state_management = True class UpdateUsers(BaseModel): enabled: bool | None = None desc: str | None = None async def main(): cli = AsyncIOMotorClient("mongodb://localhost:27017") db = cli["test_wrong_collection"] await db.drop_collection(Users.Settings.name) # insert a document use motor with extra field named "hobbies" await db[Users.Settings.name].insert_one( { "name": "lucy", "enabled": True, "created": datetime.utcnow(), "hobbies": ["swimming", "jogging"], } ) print(await db[Users.Settings.name].find_one({"name": "lucy"})) await init_beanie(db, document_models=[Users]) lucy = await Users.find_one(Users.name == "lucy") if lucy: # lucy.enabled = False _lucy = lucy.copy(update=UpdateUsers(enabled=False).dict(exclude_unset=True)) await _lucy.save() print(await db[Users.Settings.name].find_one({"name": "lucy"})) print(await db[Users.Settings.name].find_one({"name": "lucy"})) asyncio.run(main()) ``` will got result, the field `hobbies` was gone ``` {'_id': ObjectId('65430c88b86a3dce4519c935'), 'name': 'lucy', 'enabled': True, 'created': datetime.datetime(2023, 11, 2, 2, 42, 16, 556000), 'hobbies': ['swimming', 'jogging']} {'_id': ObjectId('65430c88b86a3dce4519c935'), 'revision_id': None, 'name': 'lucy', 'enabled': False, 'desc': None, 'created': datetime.datetime(2023, 11, 2, 2, 42, 16, 556000)} {'_id': ObjectId('65430c88b86a3dce4519c935'), 'revision_id': None, 'name': 'lucy', 'enabled': False, 'desc': None, 'created': datetime.datetime(2023, 11, 2, 2, 42, 16, 556000)} ``` but in recent beanie version, the same script will got the result below, the field `hobbies` is still exists ``` {'_id': ObjectId('6543091caa01b77edf0b0d1c'), 'name': 'lucy', 'enabled': True, 'created': datetime.datetime(2023, 11, 2, 2, 27, 40, 7000), 'hobbies': ['swimming', 'jogging']} {'_id': ObjectId('6543091caa01b77edf0b0d1c'), 'name': 'lucy', 'enabled': False, 'created': datetime.datetime(2023, 11, 2, 2, 27, 40, 7000), 'hobbies': ['swimming', 'jogging'], 'desc': None} {'_id': ObjectId('6543091caa01b77edf0b0d1c'), 'name': 'lucy', 'enabled': False, 'created': datetime.datetime(2023, 11, 2, 2, 27, 40, 7000), 'hobbies': ['swimming', 'jogging'], 'desc': None} ``` my question is which behavior is beanie expect (because i didn't see the changelog about this)? or the result at `1.13.0` is a bug? @roman-right