django-schema-lens
Full visibility into your Django database schema — diffs, snapshots, audits and more.
The Problem
Django migrations keep your database in sync, but they tell you nothing about what actually changed, whether a migration is safe to run in production, or what your full schema looks like right now. As a project grows, answering these questions requires reading raw migration Python, querying information_schema, or hoping your documentation is up to date.
django-schema-lens solves this by giving you a suite of manage.py commands that turn your migrations and model registry into human-readable markdown — instantly, with zero setup.
Features
- Migration diff — compare any two migrations and see exactly what changed per model
- Full schema snapshot — export every model, every field, every constraint to a single markdown file
- Model summary — one clean table listing all registered models with their fields and types
- Breaking change detector — scan all migrations and flag
ERRORandWARNlevel dangerous operations before they reach production - Migration history log — a full chronological changelog of every migration across all apps
- Zero runtime dependencies — only Django and the Python standard library
--outputflag — save any report to a file--appflag — filter any command to a single Django app
Installation
pip install django-schema-lens
Add to INSTALLED_APPS in your Django settings:
INSTALLED_APPS = [
...
"django_schema_lens",
]
Quick Start
# See what changed in the last migration
python manage.py schema_lens diff
# Export your full schema to a markdown file
python manage.py schema_lens snapshot --output schema.md
# List all models
python manage.py schema_lens models
# Check for breaking changes before deploying
python manage.py schema_lens audit
# View migration history
python manage.py schema_lens history
CLI Reference
All commands support --output FILE, --app APP, and --format markdown.
schema_lens diff
Compare the last two migrations (auto-detected), or specify two migration identifiers:
python manage.py schema_lens diff
python manage.py schema_lens diff 0002 0003
python manage.py schema_lens diff --app blog
python manage.py schema_lens diff --output diff.md
Example output:
# Migration Diff
## App: `blog`
**From:** `0001_initial` → **To:** `0002_add_published_at`
**Operations:** 2
| Operation | Model | Field / Detail |
| ----------- | ------- | --------------------------- |
| AddField | post | published_at |
| AlterField | post | title → CharField (not null)|
schema_lens snapshot
Export the full current database schema for all installed apps:
python manage.py schema_lens snapshot
python manage.py schema_lens snapshot --output schema.md
python manage.py schema_lens snapshot --app auth
Example output:
# Schema Snapshot
**Apps:** 3 | **Models:** 7
## App: `auth`
Python module: `django.contrib.auth` | Models: 3
### User
DB table: `auth_user`
| Field | Type | PK | Null | Blank | Unique | Default | DB Column |
| ------------ | ----------- | --- | ---- | ----- | ------ | ------- | ------------ |
| id | AutoField | Yes | No | No | Yes | — | id |
| username | CharField | No | No | No | Yes | — | username |
| email | CharField | No | No | Yes | No | — | email |
| is_active | BooleanField| No | No | No | No | True | is_active |
| date_joined | DateTimeField| No | No | No | No | now() | date_joined |
schema_lens models
List every registered model across all apps in a compact table:
python manage.py schema_lens models
python manage.py schema_lens models --app myapp
python manage.py schema_lens models --output models.md
Example output:
# Model Summary
**Apps:** 2 | **Models:** 5
| App | Model | DB Table | Fields | Field Names |
| ------ | ----------- | -------------- | ------ | ----------------------------------- |
| auth | User | auth_user | 11 | id, password, last_login, ... |
| auth | Group | auth_group | 2 | id, name |
| blog | Post | blog_post | 5 | id, title, body, author, created_at |
| blog | Comment | blog_comment | 4 | id, post, author, body |
schema_lens audit
Detect breaking changes in your migrations. Exits with code 1 if any ERROR-level issues are found — safe to use in CI:
python manage.py schema_lens audit
python manage.py schema_lens audit --app blog
python manage.py schema_lens audit --output audit.md
Example output:
# Breaking Change Audit
**Errors:** 1 | **Warnings:** 2 | **Total:** 3
> **1 ERROR(s) found** — these changes may cause data loss or migration failures.
| Severity | App | Migration | Operation | Model | Field / Detail | Message |
| -------- | ---- | ---------------------- | ----------- | ----- | -------------- | ----------------------------------------------- |
| ERROR | blog | 0005_remove_body | RemoveField | post | body | RemoveField 'body' — column will be dropped. |
| WARN | blog | 0006_rename_slug | RenameField | post | slug → new_slug| RenameField — code referencing old name breaks. |
| WARN | blog | 0007_alter_unique | AlterUniqueTogether | post | — | Unique constraint removed. |
Severity levels:
| Severity | Operations |
|---|---|
ERROR |
RemoveField, DeleteModel, AlterField on a non-null field |
WARN |
RenameField, RenameModel, AlterUniqueTogether removing constraints, RemoveIndex, RemoveConstraint |
schema_lens history
List all migrations chronologically across every app:
python manage.py schema_lens history
python manage.py schema_lens history --app blog
python manage.py schema_lens history --output history.md
Example output:
# Migration History
**Total migrations:** 6
| # | App | Migration | Operations | Operation Types | Dependencies |
| ---- | ---- | -------------------------- | ---------- | ---------------------- | ---------------------- |
| 0001 | auth | 0001_initial | 3 | CreateModel, ... | — |
| 0001 | blog | 0001_initial | 1 | CreateModel | auth.0001_initial |
| 0002 | blog | 0002_add_published_at | 1 | AddField | blog.0001_initial |
| 0003 | blog | 0003_alter_title | 1 | AlterField | blog.0002_add_... |
ERD Generation
Generate a visual Entity Relationship Diagram directly from your Django models — no configuration needed.
Mermaid ERD (renders on GitHub)
python manage.py schema_lens erd --output erd.md
python manage.py schema_lens erd --app blog --output blog_erd.md
The generated .md file renders automatically on GitHub:
erDiagram
Post {
AutoField id PK
CharField title
TextField content
BooleanField published
ForeignKey author FK
}
Author {
AutoField id PK
CharField name
EmailField email
}
Post }o--|| Author : author
Relationship notation:
| Symbol | Relationship |
|---|---|
}o--|| |
ForeignKey (many-to-one) |
||--|| |
OneToOneField (one-to-one) |
}o--o{ |
ManyToManyField (many-to-many) |
Field suffixes: PK — primary key · FK — foreign key · UK — unique
Interactive HTML ERD
python manage.py schema_lens erd --format html --output erd.html
Opens in any browser — no server required. Features:
- Dark-themed canvas with a card per model showing all fields and type badges
- Bezier relationship lines (solid for FK/O2O, dashed for M2M) with arrowheads
- Drag cards to rearrange the layout
- Drag background to pan the canvas
- Scroll to zoom in and out
- Click a model card to highlight its relationships
- Hover a line to see a tooltip with the field name and relation type
- Reset Layout button to restore the default grid
Filter by app
# Mermaid, filtered to a single app
python manage.py schema_lens erd --app blog
# Interactive HTML, filtered and saved to file
python manage.py schema_lens erd --app blog --format html --output blog.html
Comparison with Similar Tools
| Feature | django-schema-lens | inspectdb |
sqlmigrate |
showmigrations |
|---|---|---|---|---|
| Markdown output | Yes | No | No | No |
| Migration diff | Yes | No | No | No |
| Breaking change detection | Yes | No | No | No |
| Full schema snapshot | Yes | Partial | No | No |
| Model summary | Yes | No | No | No |
| Migration history | Yes | No | No | Partial |
| Zero dependencies | Yes | Yes | Yes | Yes |
| CI-friendly exit codes | Yes | No | No | No |
Contributing
Contributions are welcome! Please read CONTRIBUTING.md before opening a pull request.
git clone https://github.com/wikidjango/django-schema-lens.git
cd django-schema-lens
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest django_schema_lens/tests/test_all.py -v
Disclaimer
This project is not affiliated with, endorsed by, or sponsored by the Django Software Foundation or the Django project. Django is a registered trademark of the Django Software Foundation.
License
MIT License — see LICENSE for full text.
Copyright © 2026 django.wiki (Ahmad)
Release files for django-schema-lens 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_schema_lens-0.1.0.tar.gz | 34.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_schema_lens-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 67.8 kB
Release files / django_schema_lens-0.1.0.tar.gz
| Download URL | django_schema_lens-0.1.0.tar.gz |
|---|---|
| Size | 34.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2f45c730760cecd564ce8d016fb40ccc2e7507c53171de0cb084335fa9230202
|
|
BLAKE2b-256 checksum How to use checksums |
0c1c9efcf10ad05b7037682451dc91e29dec5f1f8ed83697a4cd3251ccc199fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / django_schema_lens-0.1.0-py3-none-any.whl
| Download URL | django_schema_lens-0.1.0-py3-none-any.whl |
|---|---|
| Size | 33.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b9a7b168226d6b40207269b1efa34df4b6c98a5d984374303a799d4fa8e7244a
|
|
BLAKE2b-256 checksum How to use checksums |
1b8b806a82a484f0a07957937207a78f3f6b6635a3ec9812dc3c5fd07f760bef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|