fastapi-sqlalchemy-profiler 0.1.3
SQL Profiler for FastAPI + SQLAlchemy with HTML UI
License: MIT
Requires Python: >=3.11

# fastapi-sqlalchemy-profiler

A lightweight SQL query profiler for **FastAPI** + **SQLAlchemy** applications.

This tool captures:

- All SQL queries executed per request  
- Total SQL execution time  
- Average query time  
- Slowest query  
- **N+1 query detection**  
- Beautiful, responsive **HTML dashboard** at:  



Perfect for diagnosing ORM performance issues, debugging inefficient queries, or validating database behavior during development.

---

## 🚀 Features

### 🔍 Request-Level SQL Profiling
Tracks every SQL query executed during a FastAPI request:

- SQLAlchemy Core queries  
- SQLAlchemy ORM queries  
- Queries from async `AsyncSession.execute()`  
- Queries triggered by your services, repositories, dependencies, etc.  

### ⚡ Performance Insights
- Total query time for request  
- Average query time  
- Slowest query  
- Full query text preview  

### 🟥 Automatic N+1 Detection
Automatically detects repeated SQL patterns, such as:

```sql
SELECT * FROM comments WHERE post_id = ?
SELECT * FROM comments WHERE post_id = ?
...
```

### The HTML dashboard shows:

- How many times the query repeated

- A preview of the repeated SQL

- 🎨 Modern HTML UI (Dark Mode)

- Fully responsive

- Minimalistic dark theme

- Collapsible SQL query blocks

- color-coded method badges

- No external JS or CSS

- Only builtin browser HTML/CSS

### 🎯 Zero Configuration

Enable with just:
```
app.add_middleware(SQLProfilerMiddleware, enabled=True)
app.include_router(profiler_router)
attach_sqlalchemy_listeners(engine)
```
### 📦 Installation
```
pip install fastapi-sqlalchemy-profiler
```


### 🧩 Requirements
Component	Supported Versions
- Python	3.11+
- FastAPI	Any version
- Starlette	Any version
- SQLAlchemy	1.4.x or 2.x
- Databases	PostgreSQL, MySQL, SQLite, etc.
- Async drivers	asyncpg, aiosqlite, aiomysql, etc.
### 🛠 Compatible Tech Stack

This profiler works great with:

Frameworks

- FastAPI

- Starlette

Database layers

- SQLAlchemy ORM

- SQLAlchemy Core

- AsyncEngine / AsyncSession

- Sync Engine + Session

Drivers

- asyncpg

- aiomysql

- aiosqlite

- psycopg2 / pg8000 (for sync engines)

### 🛠 Example Usage (FastAPI + SQLAlchemy Async)

Here is how to integrate it in your existing app:
```
from fastapi import FastAPI
from sqlalchemy.ext.asyncio import create_async_engine

from fastapi_sqlalchemy_profiler import (
    SQLProfilerMiddleware,
    attach_sqlalchemy_listeners,
    profiler_router
)

DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/db"

engine = create_async_engine(DATABASE_URL, echo=False)

# Attach SQLAlchemy event listeners
attach_sqlalchemy_listeners(engine)

app = FastAPI()

# Add profiler middleware (recommended only in DEBUG mode)
app.add_middleware(SQLProfilerMiddleware, enabled=True)

# Add HTML profiler UI
app.include_router(profiler_router)
```
Start your app:
```
uvicorn main:app --reload
```
Then open:
http://localhost:8000/debug/sql-profiler
### 🧪 Example Output (HTML)
### 🔥 Request Summary

```
GET /api/v1/productions
Queries: 18 • Total: 32.4 ms • Avg: 1.8 ms • Slowest: 4.1 ms
```
### 🟥 N+1 Warning
```
⚠️ N+1 queries detected

× 12
SELECT comments.id, comments.text, comments.post_id
FROM comments
WHERE comments.post_id = ?
```
### 📄 Full Query List (collapsible)

- Per-query execution time

- SQL text pretty-printed

- Expand/collapse blocks

### ⚠️ Recommended: Use Only in Development

This tool is intended for:

- local debugging

- performance tuning

- verifying ORM behavior

- diagnosing N+1 issues

- Do NOT enable in production.

For safety:
```
app.add_middleware(SQLProfilerMiddleware, enabled=settings.DEBUG)
```
### 🤝 Contributing
PRs and feature requests welcome:

- Add slow query highlighting

- Add auto-refresh mode

- Expand N+1 heuristics

- Add JSON API export

- Improve UI styling

### 📄 License

MIT License — open for personal and commercial use.

### ⭐ Like this tool?

Leave a star or contribute!
Your support helps make FastAPI development faster and debugging easier.