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.
What’s compared
Section titled “What’s compared”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:
| Status | Meaning |
|---|---|
added | Exists in this DB, missing in the other |
removed | Missing in this DB, exists in the other |
changed | Same 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.
Limits
Section titled “Limits”- 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.
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 …" } ] }}