Skip to content
ReferenceCommand line

rent migrate drift

Run drift detection after applying migrations and periodically in production:

Compare schema and database

rent migrate drift
Verified: No schema drift.

If someone changed the database outside the migration workflow:

Schema drift detected

1. add column public.posts.summary (text)
2. create index posts_author_id_idx on public.posts

Use rent migrate diff to inspect the exact repair operations.

Gate a deployment

Pass --check in CI or a deployment pipeline. Rent exits unsuccessfully when the live database differs from the RSL schema:

rent migrate drift --check
Schema drift detected

1. add column public.posts.summary (text)
2. create index posts_author_id_idx on public.posts
Error: database schema drift detected

Use JSON when a deployment system needs the complete structured operation list. --check still sets the exit status. The JSON is printed either way:

rent migrate drift --check --format json
{
  "drift": false,
  "operations": []
}

Partial-index predicates

Changing a named partial index's where condition is a schema change. Rent reports it as a drop and create under the same name. You do not need to rename the index to make a changed predicate visible. Review replacement DDL and use the normal --allow-destructive apply flag when required. This comparison also runs when optional expression metadata is missing. Supported structural spelling differences, such as redundant parentheses and SQL keyword case, are ignored. Changed operators, literals and boolean grouping remain differences. Unrecognized expressions are compared conservatively rather than silently adopting the live database's predicate.

Generated columns

A database rewrites a generated column's expression when it stores it, adding explicit casts, resolving literals to their types, and re-parenthesizing. Rent's own text and the stored form describe the same computation but never match character for character, so comparing them directly would report a difference that no migration could settle.

Rent records both forms when a migration applies, in rent.generated.json beside the migrations it describes. A drift check then compares strings: the schema's expression against the recorded one, which catches an edit, and the live expression against the recorded normalized form, which catches the database changing underneath you.

This is why drift needs no database privileges beyond reading, and works against a read-only replica. Normalizing at check time would mean creating temporary objects on whatever database is being checked, which a replica forbids and a hardened production role may not allow.

Commit rent.generated.json with the migrations. It is not part of the checksum manifest, which covers only .sql files, so it never affects migration verification.

A generated column with no recorded expression, such as one predating this file, has its expression left uncompared rather than reported. Its presence, type, and generated status are still checked. Applying the migrations again records it.