diff --git a/fastcrud/crud/fast_crud.py b/fastcrud/crud/fast_crud.py index 49a57f9..4c46291 100644 --- a/fastcrud/crud/fast_crud.py +++ b/fastcrud/crud/fast_crud.py @@ -1,5 +1,6 @@ from typing import Any, Dict, Generic, Union, Optional, Callable from datetime import datetime, timezone +import warnings from pydantic import BaseModel, ValidationError from sqlalchemy import ( @@ -2145,6 +2146,7 @@ async def update( Raises: MultipleResultsFound: If `allow_multiple` is `False` and more than one record matches the filters. + NoResultFound: If no record matches the filters. (on version 0.15.3) ValueError: If extra fields not present in the model are provided in the update data. ValueError: If `return_as_model` is `True` but `schema_to_select` is not provided. @@ -2199,7 +2201,15 @@ async def update( ) ``` """ - if not allow_multiple and (total_count := await self.count(db, **kwargs)) > 1: + total_count = await self.count(db, **kwargs) + if total_count == 0: + warnings.warn( + "Passing non-existing records to `update` will raise NoResultFound on version 0.15.3.", + DeprecationWarning, + stacklevel=2, + ) + # raise NoResultFound("No record found to update.") + if not allow_multiple and total_count > 1: raise MultipleResultsFound( f"Expected exactly one record to update, found {total_count}." ) diff --git a/tests/sqlalchemy/crud/test_get_multi_by_cursor.py b/tests/sqlalchemy/crud/test_get_multi_by_cursor.py index adec46f..ffa1fb1 100644 --- a/tests/sqlalchemy/crud/test_get_multi_by_cursor.py +++ b/tests/sqlalchemy/crud/test_get_multi_by_cursor.py @@ -124,7 +124,7 @@ async def test_get_multi_by_cursor_pagination_integrity(async_session, test_data db=async_session, object={"name": "Updated Name"}, allow_multiple=True, - name="SpecificName", + name=test_data[0]["name"], ) second_batch = await crud.get_multi_by_cursor( diff --git a/tests/sqlalchemy/crud/test_update.py b/tests/sqlalchemy/crud/test_update.py index b917f44..9680320 100644 --- a/tests/sqlalchemy/crud/test_update.py +++ b/tests/sqlalchemy/crud/test_update.py @@ -51,6 +51,18 @@ async def test_update_non_existent_record(async_session, test_data): crud = FastCRUD(ModelTest) non_existent_id = 99999 updated_data = {"name": "New Name"} + """ + In version 0.15.3, the `update` method will raise a `NoResultFound` exception: + + ``` + with pytest.raises(NoResultFound) as exc_info: + await crud.update(db=async_session, object=updated_data, id=non_existent_id) + + assert "No record found to update" in str(exc_info.value) + ``` + + For 0.15.2, the test will check if the record is not updated. + """ await crud.update(db=async_session, object=updated_data, id=non_existent_id) record = await async_session.execute( @@ -69,6 +81,18 @@ async def test_update_invalid_filters(async_session, test_data): updated_data = {"name": "New Name"} non_matching_filter = {"name": "NonExistingName"} + """ + In version 0.15.3, the `update` method will raise a `NoResultFound` exception: + + ``` + with pytest.raises(NoResultFound) as exc_info: + await crud.update(db=async_session, object=updated_data, **non_matching_filter) + + assert "No record found to update" in str(exc_info.value) + ``` + + For 0.15.2, the test will check if the record is not updated. + """ await crud.update(db=async_session, object=updated_data, **non_matching_filter) for item in test_data: diff --git a/tests/sqlmodel/crud/test_get_multi_by_cursor.py b/tests/sqlmodel/crud/test_get_multi_by_cursor.py index 764c285..7301c14 100644 --- a/tests/sqlmodel/crud/test_get_multi_by_cursor.py +++ b/tests/sqlmodel/crud/test_get_multi_by_cursor.py @@ -124,7 +124,7 @@ async def test_get_multi_by_cursor_pagination_integrity(async_session, test_data db=async_session, object={"name": "Updated Name"}, allow_multiple=True, - name="SpecificName", + name=test_data[0]["name"], ) second_batch = await crud.get_multi_by_cursor( diff --git a/tests/sqlmodel/crud/test_update.py b/tests/sqlmodel/crud/test_update.py index 9a9878d..2968674 100644 --- a/tests/sqlmodel/crud/test_update.py +++ b/tests/sqlmodel/crud/test_update.py @@ -51,6 +51,18 @@ async def test_update_non_existent_record(async_session, test_data): crud = FastCRUD(ModelTest) non_existent_id = 99999 updated_data = {"name": "New Name"} + """ + In version 0.15.3, the `update` method will raise a `NoResultFound` exception: + + ``` + with pytest.raises(NoResultFound) as exc_info: + await crud.update(db=async_session, object=updated_data, id=non_existent_id) + + assert "No record found to update" in str(exc_info.value) + ``` + + For 0.15.2, the test will check if the record is not updated. + """ await crud.update(db=async_session, object=updated_data, id=non_existent_id) record = await async_session.execute( @@ -69,6 +81,18 @@ async def test_update_invalid_filters(async_session, test_data): updated_data = {"name": "New Name"} non_matching_filter = {"name": "NonExistingName"} + """ + In version 0.15.3, the `update` method will raise a `NoResultFound` exception: + + ``` + with pytest.raises(NoResultFound) as exc_info: + await crud.update(db=async_session, object=updated_data, **non_matching_filter) + + assert "No record found to update" in str(exc_info.value) + ``` + + For 0.15.2, the test will check if the record is not updated. + """ await crud.update(db=async_session, object=updated_data, **non_matching_filter) for item in test_data: