Reading the diff
What each Drift card means, how to read the sentences, and how to navigate the result.
For: developers.
The Drift Mode screen is a list of cards. Each card describes one specific difference. This page explains the anatomy.
The hero banner
At the top of the screen, the hero shows the overall state in one of three modes:
| Banner | Meaning |
|---|---|
| Green: "In sync" | Your ORM matches the database exactly. No cards below. |
| Yellow: "N differences found" | Drift detected. Cards listed below. |
| Red: "Cannot check drift" | Parser or introspection failed. Reason shown below the banner. |
The yellow banner has a Fix All button when every drift item has an automated resolution. See the Fix button for what "automated resolution" means.
A drift card
Each card has four parts:
┌────────────────────────────────────────────────╮
│ users.email │
│ Type differs │
│ │
│ code: String │
│ db: VARCHAR(255) │
│ │
│ [Copy SQL] [Open Schema File] [···] │
╰────────────────────────────────────────────────┘| Part | What it tells you |
|---|---|
| Title | The object being described: users.email, orders.idx_user_id, posts (a table itself) |
| Status sentence | One line describing the kind of difference |
| Values | What each side has, side by side |
| Actions | Copy generated SQL, open the schema file at the relevant line, more in the overflow menu |
Status sentences
Drift Mode generates a one-line sentence that explains the difference in plain English. These are the patterns:
| Object type | Sentence example |
|---|---|
| Missing column | "Column users.deleted_at is in the database but not in your Prisma schema." |
| New column | "Column users.preferred_locale is in your Drizzle schema but not in the database." |
| Type drift | "Column orders.amount is Decimal in code but numeric(10,2) in the database." |
| Nullable drift | "Column users.last_login is nullable in the database but NOT NULL in your schema." |
| Default drift | "Column posts.published has default false in code but no default in the database." |
| Missing index | "Index idx_orders_user_id exists in the database but is not declared in your schema." |
| Missing FK | "Foreign key orders.user_id → users.id is not enforced in the database." |
| FK rule drift | "Foreign key orders.user_id has ON DELETE CASCADE in code but RESTRICT in the database." |
| Missing table | "Table audit_log exists in the database but no model declares it." |
When you can't tell at a glance which side is "right", the sentence is intentionally neutral — Drift Mode doesn't assume your code or your database is the source of truth.
Severity coloring
Cards are tinted by severity:
| Color | Meaning | Examples |
|---|---|---|
| Yellow | Cosmetic or low-risk | Default value drift, comment drift, additive columns |
| Orange | Code might misbehave | Type drift on a column the app reads, nullable drift |
| Red | Code will break | Missing tables, missing required columns, FK rule changes that affect cascades |
Severity is a heuristic. It's not a guarantee that yellow drift is safe to leave alone — it's a hint for where to look first.
Filtering
The toolbar above the cards has filters:
- By status — show only
missing in DB,missing in code, ordifferent. - By object type — tables, columns, indexes, foreign keys.
- By table — type a table name to narrow to one table.
- By severity — yellow / orange / red.
Filters compose. Selecting "Red + indexes + table:orders" gives you all critical index drift on the orders table.
Sorting
Cards default to sorted by:
- Severity (red first)
- Object type (tables first, then columns, indexes, FKs)
- Alphabetical table.object name
To group by table instead, switch the sort dropdown to "Group by table".
Card overflow menu
The ··· button on each card opens additional actions:
| Action | What it does |
|---|---|
| Copy generated SQL | Puts the would-be DDL on your clipboard, ready to paste into the editor |
| Open schema file at line | Opens your ORM schema file in your default editor, scrolled to the relevant line |
| Open table in QueryDeck | Switches to Table Mode for the affected table |
| Suppress this drift | Adds an entry to .querydeck/drift-ignore.yml so this specific item is hidden in future scans |
| Send to AI | Drops the drift sentence + values into the AI assistant for a deeper explanation or fix suggestion |
Suppressing false positives
Some drift is intentional — a column the database has for ops or backups, an index added by a DBA, a default that's set by a trigger instead of a column default. To stop seeing it:
- Click
···on the card →Suppress this drift. - The card disappears. The drift is now in
.querydeck/drift-ignore.ymlin your project root. - Commit the file. Your teammates see the same filtered view.
To unsuppress, edit the YAML file. Each entry looks like:
- table: users
object: deleted_at
reason: "Soft-delete column managed outside the ORM"When the parser fails
If Drift Mode can't parse your ORM schema, the card list shows the parser error. Common causes:
- Newer ORM syntax than QueryDeck supports yet (e.g., Prisma preview features).
- Schema split across many files in a non-standard layout.
- Custom config that points the ORM at a different file than QueryDeck looks at.
If parsing fails, the rest of QueryDeck still works — only Drift Mode is unavailable for that connection. File a bug with the schema snippet (sensitive parts redacted).
What's next
- The Fix button — what gets executed when you click it
- Supported ORMs — what each parser does and doesn't read