Skip to content

Commit 29e6b43

Browse files
committed
fix: add MSSQL dialect fallback for composite PK delete_many
MSSQL doesn't support tuple().in_() syntax for row value comparisons. Use OR of AND conditions as fallback for MSSQL dialect. Also fix mock repositories in unit tests to initialize _pk_columns and _pk_attr_names attributes required by composite PK support.
1 parent 32cb13a commit 29e6b43

3 files changed

Lines changed: 15 additions & 2 deletions

File tree

advanced_alchemy/repository/_async.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,11 @@ async def delete_many(
12461246

12471247
for idx in range(0, len(normalized_ids), effective_chunk_size):
12481248
chunk = normalized_ids[idx : min(idx + effective_chunk_size, len(normalized_ids))]
1249-
pk_filter = tuple_(*self._pk_columns).in_(chunk)
1249+
pk_filter = (
1250+
or_(*[self._build_pk_filter(pk_tuple) for pk_tuple in chunk])
1251+
if self._dialect.name == "mssql"
1252+
else tuple_(*self._pk_columns).in_(chunk)
1253+
)
12501254

12511255
if self._dialect.delete_executemany_returning:
12521256
returning_delete_stmt = delete(self.model_type).where(pk_filter).returning(self.model_type)

advanced_alchemy/repository/_sync.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,11 @@ def delete_many(
12471247

12481248
for idx in range(0, len(normalized_ids), effective_chunk_size):
12491249
chunk = normalized_ids[idx : min(idx + effective_chunk_size, len(normalized_ids))]
1250-
pk_filter = tuple_(*self._pk_columns).in_(chunk)
1250+
pk_filter = (
1251+
or_(*[self._build_pk_filter(pk_tuple) for pk_tuple in chunk])
1252+
if self._dialect.name == "mssql"
1253+
else tuple_(*self._pk_columns).in_(chunk)
1254+
)
12511255

12521256
if self._dialect.delete_executemany_returning:
12531257
returning_delete_stmt = delete(self.model_type).where(pk_filter).returning(self.model_type)

tests/unit/test_service_to_model_flow.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import pytest
1515

1616
from advanced_alchemy.repository import SQLAlchemyAsyncRepository, SQLAlchemySyncRepository
17+
from advanced_alchemy.repository._util import get_primary_key_info
1718
from advanced_alchemy.service import SQLAlchemyAsyncRepositoryService, SQLAlchemySyncRepositoryService
1819
from advanced_alchemy.service.typing import ATTRS_INSTALLED, MSGSPEC_INSTALLED, PYDANTIC_INSTALLED, ModelDictT
1920

@@ -33,6 +34,8 @@ def __init__(self) -> None:
3334
# Don't call super().__init__ to avoid needing session
3435
self.model_type = MockModel
3536
self.id_attribute = "id"
37+
# Initialize PK info for composite PK support
38+
self._pk_columns, self._pk_attr_names = get_primary_key_info(MockModel)
3639

3740

3841
class MockSyncRepository(SQLAlchemySyncRepository[MockModel]):
@@ -44,6 +47,8 @@ def __init__(self) -> None:
4447
# Don't call super().__init__ to avoid needing session
4548
self.model_type = MockModel
4649
self.id_attribute = "id"
50+
# Initialize PK info for composite PK support
51+
self._pk_columns, self._pk_attr_names = get_primary_key_info(MockModel)
4752

4853

4954
class TrackingService(SQLAlchemyAsyncRepositoryService[MockModel, MockRepository]):

0 commit comments

Comments
 (0)