Skip to content

prefer-bulk-upsert

Use a declared compatible upsert_many instead of discarded serial upserts.

Why

A loop of independent singleton writes repeats database calls while an existing bulk command centralizes conflict handling and batch execution.

Fix

Collect commands and call upsert_many in bounded batches after reviewing duplicate keys, failure atomicity, ordering, and tenant scope. Preserve deliberately per-row transactions or effects with an exact suppression.

Examples

Before — flagged Collect writes for an available bulk command
app/service.py
class UserStore:
async def upsert(self, user: UserInput) -> User: ...
async def upsert_many(self, users: list[UserInput]) -> list[User]: ...
async def save(store: UserStore, users: list[UserInput]):
for user in users:
await store.upsert(user)
After — preferred Use the existing bulk command
app/service.py
class UserStore:
async def upsert(self, user: UserInput) -> User: ...
async def upsert_many(self, users: list[UserInput]) -> list[User]: ...
async def save(store: UserStore, users: list[UserInput]):
await store.upsert_many(users)