Database migration safety
Check the SQL the migration tool will actually execute
A short ORM change can generate a costly or incompatible database operation. Review the emitted SQL and its production consequences before approval.
In this article
Compare intent with execution
A developer may intend to make a field easier to query, while the generated migration changes its type, rebuilds an index or replaces a column. Review the SQL rather than relying only on the application model diff.
Confirm table and column names, defaults, constraints and dependency changes. Look for accidental drops caused by renaming a model property without an explicit database rename or transition.
Check the migration against the exact database version. Behaviour remembered from another engine or release is not sufficient evidence for a production change.
Examine waiting and work
Determine the lock requirements and whether the command scans or rewrites data. Consider long-running transactions and concurrent application writes.
For PostgreSQL, concurrent index creation has different execution restrictions from a regular index build, including that it cannot run inside a transaction block. A migration tool that wraps every step in a transaction needs an appropriate mechanism for such a command.
Review waiting limits, progress visibility and cleanup after failure. A safe command without a safe execution wrapper can still produce a difficult incident.
Inspect the data assumptions
Before adding a constraint, establish whether existing rows satisfy it. Define how exceptions are resolved and who approves any business-data correction.
Check conversion boundaries such as precision, length, nullability and timezone interpretation. A syntactically valid cast may lose information or assign a meaning the old data never had.
Review live writers during the backfill. They must not create new violations faster than the migration repairs old ones. Validation of a static snapshot alone cannot establish the final invariant.
Require a recovery demonstration
Run the migration, interrupt it at a meaningful point and resume from the observed state. Exercise the supported old and new application versions against the result.
For destructive changes, state what recovery preserves and what it cannot. A reverse migration that recreates an empty column does not restore the values that were dropped.
Attach concise evidence to the review: the executed SQL, representative rehearsal results, unresolved data exceptions and the rollback boundary. These details let a reviewer assess the real operation instead of approving a reassuring migration filename.
Primary sources
PostgreSQL: CREATE INDEXPostgreSQL: ALTER TABLEReferences checked 11 September 2026.