prefer-application-model-joins
Compose distinct model records in application code instead of a cross-model SQL join.
Why
A SQL join across separate persistence relations couples their read representations and can bypass the owning store's access and conversion policy. This architecture prefers bounded store reads and typed application composition when their consistency contract permits it.
Fix
Review the relation owners, then load the related records through their typed stores, batch by IDs and compose them in application code. Preserve tenant filters, null-extension, cardinality, snapshot consistency, authorization and FOR UPDATE locks. Keep an explained exception for an atomic database operation; replacing a join with unrelated reads can change behavior or introduce N+1 queries.
Examples
from psycopg import AsyncCursor
async def load(cursor: AsyncCursor): await cursor.execute( 'SELECT s.id, u.email FROM scenario s LEFT JOIN "user" u ON u.id = s.actor_id WHERE s.id = %s', (1,), )from psycopg import AsyncCursor
async def load(cursor: AsyncCursor): await cursor.execute( "SELECT s.id, u.email FROM scenario s LEFT JOIN scenario u ON u.id = s.actor_id WHERE s.id = %s", (1,), )