prefer-bulk-upsert
Use declared compatible bulk APIs for repeated singleton reads and writes.
Why
Serial singleton calls and eager coroutine fan-out can repeat database or remote work. A source-declared compatible bulk API identifies an opportunity to review batching, including bulk implementations that repeat backend singleton calls.
Fix
Collect inputs and use the declared bulk API in bounded batches after reviewing missing rows, cardinality, duplicate keys, ordering, failure atomicity, concurrency, cancellation, backpressure, tenant scope, and transaction or snapshot behavior. Preserve deliberately per-row transactions or effects with an exact suppression.
Examples
class UserStore: async def get(self, key: str) -> User | None: ... async def get_many(self, keys: list[str]) -> list[User]: ...
async def load(store: UserStore, keys: list[str]): return [await store.get(key) for key in keys]class UserStore: async def get(self, key: str) -> User | None: ... async def get_many(self, keys: list[str]) -> list[User]: ...
async def load(store: UserStore, keys: list[str]): return await store.get_many(keys)import asyncio
class UserStore: async def get(self, key: str) -> User | None: ... async def get_many(self, keys: list[str]) -> list[User]: ...
async def load(store: UserStore, keys: list[str]): return await asyncio.gather(*(store.get(key) for key in keys))class UserStore: async def get(self, key: str) -> User | None: ... async def get_many(self, keys: list[str]) -> list[User]: ...
async def load(store: UserStore, keys: list[str]): return await store.get_many(keys)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)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)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]): return [await store.upsert(user) for user in users]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]): return await store.upsert_many(users)