SchemaDrift compares two versions of a database schema and tells you what changed and which changes will break running code. Paste the old and new schema, get a colour-coded report: BREAKING, REVIEW or SAFE. An example pair is preloaded, so the demo works the moment it opens.
Most outages from database migrations are avoidable. A dropped column, a new NOT NULL without a default, or a narrowed type looks harmless in a pull request and fails in production. SchemaDrift catches these before they ship:
- Review a migration pull request in seconds instead of reading DDL line by line.
- Run it as a check in CI to stop a breaking schema change from merging unnoticed.
- Explain to teammates exactly why a change is risky.
- Reads SQL DDL (
CREATE TABLE,CREATE INDEX,ALTER TABLE ... ADD) or JSON, auto-detected. - Classifies every change as breaking, review or safe, with a plain-English reason.
- Flags a possible rename when a column is dropped and another of the same type is added.
- Works as a web UI and as a Python library.
- No database connection, no secrets, no setup.
A dropped column plus an added column of the same type is flagged as a possible rename. A rename is still breaking for code that uses the old name.
- Open the app. An example pair is already loaded.
- Paste your current schema on the left and the proposed schema on the right. Both SQL DDL (
CREATE TABLE,CREATE INDEX,ALTER TABLE ... ADD) and JSON are accepted. - Press Compare schemas. Read the verdict at the top, then each change with its reason.
JSON format:
{
"tables": {
"users": {
"columns": {
"id": {"type": "bigint", "nullable": false},
"email": {"type": "varchar(100)", "nullable": false, "default": null}
},
"primary_key": ["id"],
"indexes": {"uq_email": {"columns": ["email"], "unique": true}},
"foreign_keys": []
}
}
}Use it from Python:
from schemadrift import load_schema, diff_schemas, summarize
changes = diff_schemas(load_schema(old_sql), load_schema(new_sql))
print(summarize(changes)["verdict"]) # BREAKING / REVIEW / SAFE / NO CHANGESPOST /api/diff takes {"old": ..., "new": ...} (SQL text, or a JSON schema object) and returns the summary and every change. It answers 422 for a schema it cannot read and 413 above 512 KB.
curl -s -X POST https://schema-drift-nine.vercel.app/api/diff \
-H 'Content-Type: application/json' \
-d '{"old": "CREATE TABLE t (id INT PRIMARY KEY, n INT);", "new": "CREATE TABLE t (id INT PRIMARY KEY);"}'In CI, fail the job when summary.verdict is BREAKING.
For the built-in example (a proposed v2 of a users and orders schema) SchemaDrift reports 6 breaking, 2 review, 7 safe, including:
- BREAKING: table
legacy_auditwas dropped - BREAKING:
users.tenant_idisNOT NULLwith no default - BREAKING:
orders.totalnarrowed fromdecimal(10,2)todecimal(8,2) - BREAKING: unique constraint added on
users(email) - REVIEW:
orders.statuslost its default - SAFE:
users.emailwidened fromvarchar(100)tovarchar(255)
You need Python 3.10 or newer. No environment variables or secrets are required. The only optional setting is the port.
git clone https://github.com/ChethankumarGS/SchemaDrift.git
cd SchemaDrift
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
python app.py # http://localhost:5000Optional: PORT=8000 python app.py to change the port.
Run the tests:
python -m pytest -qapp.py Flask app (/, /api/diff, /healthz)
schemadrift/parser.py SQL DDL and JSON to a common schema model
schemadrift/diff.py diff engine and breaking / review / safe rules
schemadrift/examples.py built-in demo schemas
templates/index.html report UI
docs/demo.svg demo screenshot used in this README
tests/ parser, diff and API tests
render.yaml optional Render blueprint
The app is deployed on Vercel with zero configuration (Flask preset). It also runs on Render's free plan using the included render.yaml (gunicorn app:app).
SchemaDrift reads common DDL (CREATE TABLE, CREATE INDEX, ALTER TABLE ... ADD). Views, triggers, stored procedures, check constraints and engine-specific options are ignored. Renames cannot be detected with certainty.
Chethan Kumar - GitHub
