Skip to content

Commit 3a2ced4

Browse files
cofinpeterschutt
andauthored
feat: verify the service has an identity before updating. (#71)
Co-authored-by: Peter Schutt <peter.github@proton.me>
1 parent f74cad4 commit 3a2ced4

3 files changed

Lines changed: 19 additions & 0 deletions

File tree

advanced_alchemy/service/_async.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from sqlalchemy.orm import InstrumentedAttribute
1212

13+
from advanced_alchemy.exceptions import RepositoryError
1314
from advanced_alchemy.repository._util import model_from_dict
1415
from advanced_alchemy.repository.typing import ModelT
1516

@@ -316,6 +317,12 @@ async def update(
316317
data = await self.to_model(data, "update")
317318
if isinstance(id_attribute, InstrumentedAttribute):
318319
id_attribute = cast("str", id_attribute.description)
320+
if item_id is None and self.repository.get_id_attribute_value(item=data, id_attribute=id_attribute) is None:
321+
msg = (
322+
"Could not identify ID attribute value. One of the following is required: "
323+
f"``item_id`` or ``data.{id_attribute or self.repository.id_attribute}``"
324+
)
325+
raise RepositoryError(msg)
319326
if item_id is not None:
320327
data = self.repository.set_id_attribute_value(item_id=item_id, item=data, id_attribute=id_attribute)
321328
return await self.repository.update(

advanced_alchemy/service/_sync.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from sqlalchemy.orm import InstrumentedAttribute, Session
1414

15+
from advanced_alchemy.exceptions import RepositoryError
1516
from advanced_alchemy.repository._util import model_from_dict
1617
from advanced_alchemy.repository.typing import ModelT
1718

@@ -317,6 +318,12 @@ def update(
317318
data = self.to_model(data, "update")
318319
if isinstance(id_attribute, InstrumentedAttribute):
319320
id_attribute = cast("str", id_attribute.description)
321+
if item_id is None and self.repository.get_id_attribute_value(item=data, id_attribute=id_attribute) is None:
322+
msg = (
323+
"Could not identify ID attribute value. One of the following is required: "
324+
f"``item_id`` or ``data.{id_attribute or self.repository.id_attribute}``"
325+
)
326+
raise RepositoryError(msg)
320327
if item_id is not None:
321328
data = self.repository.set_id_attribute_value(item_id=item_id, item=data, id_attribute=id_attribute)
322329
return self.repository.update(

tests/integration/test_repository.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,3 +1550,8 @@ async def test_repo_get_or_create_deprecation(author_repo: AuthorRepository, fir
15501550
existing_obj, existing_created = await maybe_async(author_repo.get_or_create(name="Agatha Christie"))
15511551
assert existing_obj.id == first_author_id
15521552
assert existing_created is False
1553+
1554+
1555+
async def test_service_update_no_pk(author_service: AuthorService) -> None:
1556+
with pytest.raises(RepositoryError):
1557+
_existing_obj = await maybe_async(author_service.update(data={"name": "Agatha Christie"}))

0 commit comments

Comments
 (0)