diff --git a/beanie/__init__.py b/beanie/__init__.py index e690f12c..24e03fd9 100644 --- a/beanie/__init__.py +++ b/beanie/__init__.py @@ -23,6 +23,7 @@ WriteRules, DeleteRules, ) +from beanie.odm.queries.update import UpdateResponse from beanie.odm.settings.timeseries import TimeSeriesConfig, Granularity from beanie.odm.utils.init import init_beanie from beanie.odm.documents import Document @@ -64,4 +65,6 @@ "DeleteRules", # Custom Types "DecimalAnnotation", + # UpdateResponse + "UpdateResponse", ] diff --git a/beanie/odm/utils/parsing.py b/beanie/odm/utils/parsing.py index b3d3f2d1..d1b03af8 100644 --- a/beanie/odm/utils/parsing.py +++ b/beanie/odm/utils/parsing.py @@ -43,6 +43,7 @@ def merge_models(left: BaseModel, right: BaseModel) -> None: break if links_found: continue + left.__setattr__(k, right_value) elif not isinstance(right_value, Link): left.__setattr__(k, right_value) diff --git a/docs/tutorial/update.md b/docs/tutorial/update.md index d9034bb0..bef86213 100644 --- a/docs/tutorial/update.md +++ b/docs/tutorial/update.md @@ -80,3 +80,12 @@ await Product.find_one(Product.name == "Milka").delete() await Product.find(Product.category.name == "Chocolate").delete() ``` + +## Response Type + +For the object methods `update` and `upsert`, you can use the `response_type` parameter to specify the type of response. + +The options are: +- `UpdateResponse.UPDATE_RESULT` - returns the result of the update operation. +- `UpdateResponse.NEW_DOCUMENT` - returns the newly updated document. +- `UpdateResponse.OLD_DOCUMENT` - returns the document before the update. diff --git a/tests/odm/conftest.py b/tests/odm/conftest.py index f45b18f7..a5360e65 100644 --- a/tests/odm/conftest.py +++ b/tests/odm/conftest.py @@ -86,6 +86,7 @@ DocumentWithCustomInit, DocumentWithTextIndexAndLink, LinkDocumentForTextSeacrh, + TestDocumentWithList, ) from tests.odm.views import TestView, TestViewWithLink @@ -257,6 +258,7 @@ async def init(db): DocumentWithCustomInit, DocumentWithTextIndexAndLink, LinkDocumentForTextSeacrh, + TestDocumentWithList, ] await init_beanie( database=db, diff --git a/tests/odm/documents/test_update.py b/tests/odm/documents/test_update.py index adc941d4..4a2e2072 100644 --- a/tests/odm/documents/test_update.py +++ b/tests/odm/documents/test_update.py @@ -9,6 +9,7 @@ DocumentTestModel, ModelWithOptionalField, DocumentWithKeepNullsFalse, + TestDocumentWithList, ) @@ -278,3 +279,13 @@ async def test_save_changes_keep_nulls_false(): # {"test_str": "smth_else"}, session=session # ).to_list() # assert len(smth_else_documetns) == 17 + + +async def test_update_list(): + test_record = TestDocumentWithList(list_values=["1", "2", "3"]) + test_record = await test_record.insert() + update_data = test_record.dict() + update_data["list_values"] = ["5", "6", "7"] + + updated_test_record = await test_record.update({"$set": update_data}) + assert updated_test_record.list_values == update_data["list_values"] diff --git a/tests/odm/models.py b/tests/odm/models.py index b3bfa19d..320679b0 100644 --- a/tests/odm/models.py +++ b/tests/odm/models.py @@ -854,3 +854,7 @@ class Settings: name="text_index", ) ] + + +class TestDocumentWithList(Document): + list_values: List[str] diff --git a/tests/odm/query/test_update.py b/tests/odm/query/test_update.py index f0025660..977734f0 100644 --- a/tests/odm/query/test_update.py +++ b/tests/odm/query/test_update.py @@ -3,6 +3,7 @@ import pytest from beanie.odm.operators.update.general import Set, Max +from beanie.odm.queries.update import UpdateResponse from tests.odm.models import Sample @@ -194,6 +195,22 @@ async def test_update_one_upsert_without_insert( assert len(new_docs) == 0 +async def test_update_one_upsert_without_insert_return_doc( + preset_documents, sample_doc_not_saved +): + result = await Sample.find_one(Sample.integer > 1).upsert( + Set({Sample.integer: 100}), + on_insert=sample_doc_not_saved, + response_type=UpdateResponse.NEW_DOCUMENT, + ) + assert isinstance(result, Sample) + + new_docs = await Sample.find_many( + Sample.string == sample_doc_not_saved.string + ).to_list() + assert len(new_docs) == 0 + + async def test_update_pymongo_kwargs(preset_documents): with pytest.raises(TypeError): await Sample.find_many(Sample.increment > 4).update( diff --git a/tests/odm/test_relations.py b/tests/odm/test_relations.py index 80bded59..ef8298ea 100644 --- a/tests/odm/test_relations.py +++ b/tests/odm/test_relations.py @@ -172,6 +172,7 @@ async def test_multi_insert_links(self): house.windows.append(new_window) await house.save(link_rule=WriteRules.WRITE) for win in house.windows: + print(type(win), win) assert isinstance(win, Window) assert win.id