DEV Community

Yongho Hwang
Yongho Hwang

Posted on

Tune your Django/SQLAlchemy queries with a Claude Code plugin

query-inspector is a Claude Code plugin that inspects the SQL and ORM-generated queries in your code without running the app.

It reports N+1s, missing indexes, and other anti-patterns with paste-ready fixes. It reads the code and infers the SQL your ORM will generate - no app boot, no production database.

As of 1.1.0 it covers Python (Django/SQLAlchemy) alongside the JVM stacks it started with.

The problem

An ORM hides the SQL it generates. The usual way to find a query problem is to run it - APM, slow-query logs, django-debug-toolbar.

DB problems like slow queries are hard to catch even in QA and usually surface in production - where you end up fixing them on a running service.

query-inspector reads the code instead and surfaces the SQL problem statically, without running anything.

In a tight code-build loop, running it once right before a commit scans only the diff - so you catch and fix issues quickly.

What it checks (Python)

It routes Django/SQLAlchemy code through adapters, reconstructs the SQL, and checks it against your schema.

  • N+1 - relationships touched in a loop, templates, serializer fields, a model __str__ in an admin list. It looks beyond the view.
  • Missing indexes - Django auto-indexes FKs; SQLAlchemy doesn't. On SQLAlchemy + PostgreSQL a user_id FK with no index=True is flagged; the Django equivalent isn't (no false positive).
  • Join-less cross-entity refs - a .any() with no join compiles to a non-correlated EXISTS that passes every row - a permission filter that doesn't filter. Invisible in code; visible only in the compiled SQL.
  • Dialect & migrations - Alembic and Django migrations are read as a first-class index source.

Inferred queries are labeled INFERRED/AMBIGUOUS, and the key ones are compile-verified.

How it differs from a linter or APM

  • No run required - no waiting for a slow request to show up in a trace.
  • Wider N+1 reach - templates, serializers, admin, not just the view.
  • Fixes, not just findings - a CREATE INDEX, a selectinload(...), paste-ready. It suggests; it never edits your code.

How it works

Three tiers, degrading automatically:

  1. Static heuristics - no DB, always on.
  2. Schema context - models/migrations confirm index coverage; concrete CREATE INDEX.
  3. Live EXPLAIN - only with --db, read-only, production hosts blocked.

Kotlin/Java is the primary focus and Python is an extension; 1.1.0 validated the Python adapters against real open-source projects.

Try it

claude plugin marketplace add jogakdal/query-inspector
claude plugin install query-inspector@query-inspector-marketplace
Enter fullscreen mode Exit fullscreen mode

In your project directory, open a new Claude session and run:

/query-inspector:tuning-report
Enter fullscreen mode Exit fullscreen mode

/query-inspector:inventory-report catalogs every query the project runs. For the full manual, see the README in the repo below.

Repo (MIT): https://github.com/jogakdal/query-inspector

Run it on your own project and tell me what it caught - or got wrong.

Top comments (0)