Query-shaped call inside a loop (generic N+1 heuristic)
Part of Code Quality & Syntax, which counts for 20% of the overall score. When this check fires it deducts 4 points from that category, once per scan, no matter how many places it turns up.
What it detects
A call shaped like a database/ORM query (.query(), .execute(), or .filter()) runs once per loop iteration, the classic N+1 pattern: what could be one batched query becomes n round trips. This rule is deliberately framework-agnostic and generic (it does not know Django or SQLAlchemy specifically); framework-specific packs cover their own ORM N+1 shapes more precisely. Heuristic: it cannot confirm the call actually hits a database.
Why it matters
A call shaped like a database or ORM query (.query(), .execute(), or .filter()) running once per loop iteration is the classic N+1 pattern: what could be a single batched query becomes n separate round trips to the database, and each round trip carries its own network and query-planning overhead. This rule is deliberately generic and framework-agnostic; it does not know the specifics of Django's or Rails' ORMs; it exists to catch the same shape of mistake in code that is not using either. It cannot confirm the call actually reaches a real database, so verify before treating it as certain.
How to fix it
Move the query outside the loop: fetch everything needed in one batched query (using an IN clause, a join, or a bulk-fetch method your ORM/driver provides) keyed on the set of ids/values you would otherwise have queried one at a time, then look up each loop iteration's data from the already-fetched result in memory.
The paid report includes a ready-to-paste prompt for your AI coding agent for every check it finds, pointed at the exact findings from your scan. See pricing
Does your repo trip this check?
Paste a GitHub URL or drop a project folder. Scans run in your browser and take seconds.
Scan your repo