Skip to content
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

Improve update method when item is not found #176

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion fastcrud/crud/fast_crud.py
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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}."
)
Expand Down
2 changes: 1 addition & 1 deletion tests/sqlalchemy/crud/test_get_multi_by_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
24 changes: 24 additions & 0 deletions tests/sqlalchemy/crud/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion tests/sqlmodel/crud/test_get_multi_by_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
24 changes: 24 additions & 0 deletions tests/sqlmodel/crud/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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:
Expand Down
Loading