Skip to content

Schema diff

PerSQL ships with a built-in schema diff between any two databases in the same namespace. It works on the same sqlite_master data SQLite emits for .schema, sorted and paired so you see exactly what’s added, removed, or changed.

Find it on a database’s Migrations tab — pick another database from the dropdown, click Diff.

Every row in sqlite_master with a non-null sql field, excluding SQLite-internal (sqlite_*) and Cloudflare-internal (_cf_*) names:

  • Tables (CREATE TABLE …)
  • Indexes (CREATE INDEX …)
  • Views (CREATE VIEW …)
  • Triggers (CREATE TRIGGER …)

Items are paired by (type, name) and classified as:

StatusMeaning
addedExists in this DB, missing in the other
removedMissing in this DB, exists in the other
changedSame name on both sides, different sql

The convention reads as “what would have to change in the other DB to match this one”. Useful pattern: fork a database to staging, make changes, diff staging against prod to see exactly the migration you’d need to apply.

  • Same namespace only (cross-namespace diff is a future feature).
  • Whole-row text comparison — semantically equivalent SQL with different whitespace will show as changed. Run a formatter on both sides if that matters.
  • Diff doesn’t compare data, only schema.
Terminal window
curl --cookie cookies.txt \
https://api.persql.com/api/namespaces/acme/databases/orders/diff \
-d '{"otherDbSlug": "orders-staging"}'

Response:

{
"success": true,
"data": {
"leftDb": "orders-staging",
"rightDb": "orders",
"added": [ { "type": "index", "name": "idx_…", "afterSql": "CREATE INDEX …" } ],
"removed": [ { "type": "table", "name": "scratch", "beforeSql": "CREATE TABLE …" } ],
"changed": [ { "type": "table", "name": "orders", "beforeSql": "CREATE TABLE …", "afterSql": "CREATE TABLE …" } ]
}
}