Skip to content

no-psycopg-execution-outside-injected-owner

Psycopg execution occurs outside a constructor-injected persistence owner.

Why

Free helpers and locally created clients can split query and transaction ownership across unrelated call sites, making persistence behavior harder to change consistently.

Fix

Move the operation behind a store, repository, or narrow transaction owner that receives its Psycopg pool or connection through the constructor. Use an exact SARJ415 suppression when direct execution is the deliberate behavior under test.

Examples

Before — flagged Do not execute persistence operations in a free helper
app/retry_rows.py
from psycopg_pool import AsyncConnectionPool
async def mark(pool: AsyncConnectionPool):
async with pool.connection() as conn:
await conn.execute("UPDATE call SET retry = true")
After — preferred Execute through an injected persistence owner
app/store.py
from psycopg_pool import AsyncConnectionPool
class Store:
def __init__(self, pool: AsyncConnectionPool):
self.pool = pool
async def save(self):
async with self.pool.connection() as conn:
await conn.execute("UPDATE call SET retry = true")

Formerly: sql-requires-injected-pool-owner