Skip to content
Open
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
4 changes: 4 additions & 0 deletions advanced_alchemy/service/_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,10 @@ def filter_unset(attr: Any, value: Any) -> bool: # noqa: ARG001
**asdict(data, filter=filter_unset),
)

# Check if data is already an instance of the expected model type
if isinstance(data, self.model_type):
return cast("ModelT", data)

# Fallback for objects with __dict__ (e.g., regular classes)
if hasattr(data, "__dict__"):
return model_from_dict(
Expand Down
4 changes: 4 additions & 0 deletions advanced_alchemy/service/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,10 @@ def filter_unset(attr: Any, value: Any) -> bool: # noqa: ARG001
**asdict(data, filter=filter_unset),
)

# Check if data is already an instance of the expected model type
if isinstance(data, self.model_type):
return cast("ModelT", data)

# Fallback for objects with __dict__ (e.g., regular classes)
if hasattr(data, "__dict__"):
return model_from_dict(
Expand Down
26 changes: 23 additions & 3 deletions tests/integration/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,19 @@ async def test_repo_update_method(seeded_test_session_async: "tuple[AsyncSession
# Get first author
authors = await maybe_async(author_repo.list())
author = authors[0]

original_name = author.name
original_created_at = author.created_at
original_updated_at = author.updated_at

# Update the author
author.name = "Updated Name"
updated_author = await maybe_async(author_repo.update(author))

assert updated_author.name == "Updated Name"
assert updated_author.name != original_name
assert updated_author.created_at == original_created_at
assert updated_author.updated_at > original_updated_at


async def test_repo_update_many_method_stale_data_fix(
Expand Down Expand Up @@ -385,7 +390,7 @@ async def test_repo_update_many_method_stale_data_fix(
# updated_at should be newer than before
if updated_author.id == authors[0].id:
assert updated_author.created_at == original_created_at
assert updated_author.updated_at >= original_updated_at
assert updated_author.updated_at > original_updated_at


async def test_repo_update_many_mixed_types(seeded_test_session_async: "tuple[AsyncSession, dict[str, type]]") -> None:
Expand Down Expand Up @@ -498,11 +503,18 @@ async def test_service_update_method(seeded_test_session_async: "tuple[AsyncSess
author = authors[0]
author_id = author.id

original_name = author.name
original_created_at = author.created_at
original_updated_at = author.updated_at

# Update via service - correct parameter order is (data, item_id)
update_data = {"name": "Service Updated Name"}
updated_author = await maybe_async(author_service.update(update_data, item_id=author_id))
author.name = "Service Updated Name"
updated_author = await maybe_async(author_service.update(author, item_id=author_id))

assert updated_author.name == "Service Updated Name"
assert updated_author.name != original_name
assert updated_author.created_at == original_created_at
assert updated_author.updated_at > original_updated_at


async def test_service_delete_method(seeded_test_session_async: "tuple[AsyncSession, dict[str, type]]") -> None:
Expand Down Expand Up @@ -679,6 +691,10 @@ async def test_service_update_many_schema_types_github_535(

original_dob1 = author1.dob
original_dob2 = author2.dob
original_created_at1 = author1.created_at
original_created_at2 = author2.created_at
original_updated_at1 = author1.updated_at
original_updated_at2 = author2.updated_at

# Get ID type from model for dynamic schema creation
# For Pydantic compatibility, we need to map database-specific types to Python types
Expand Down Expand Up @@ -720,9 +736,13 @@ class AuthorUpdateMsgspecSchema(msgspec.Struct): # type: ignore[name-defined,mi
# Verify: names were updated, but dobs remain unchanged
assert updated_author1.name == "Updated Author One"
assert updated_author1.dob == original_dob1 # Should be unchanged
assert updated_author1.created_at == original_created_at1
assert updated_author1.updated_at > original_updated_at1

assert updated_author2.name == "Updated Author Two"
assert updated_author2.dob == original_dob2 # Should be unchanged
assert updated_author2.created_at == original_created_at2
assert updated_author2.updated_at > original_updated_at2


async def test_repo_update_many_non_returning_backend_refresh(
Expand Down
Loading