SchemaRisk
Stop dangerous database migrations before they reach production.
SchemaRisk is a production-grade PostgreSQL migration safety analyzer.
It understands your migrations the way a senior DBA does — flags dangerous operations, generates safe alternatives, and posts risk reports directly in your pull requests.
Why SchemaRisk
Schema migrations fail in production for predictable reasons:
ALTER TABLE ... ALTER COLUMN TYPErewrites the entire table under lockCREATE INDEXwithoutCONCURRENTLYblocks all writes for minutesDROP COLUMNbreaks application code before it's been removedADD COLUMN NOT NULLfails instantly on tables with existing rowsADD COLUMN DEFAULTon PostgreSQL 10 rewrites the table; on PG11+ it's free
SchemaRisk detects all of these, explains exactly why they are dangerous, and gives you the step-by-step safe alternative.
Key Features
| Feature | Description |
|---|---|
| Risk scoring | Every dangerous operation scored by severity + table size |
| PG version-aware rules | ADD COLUMN DEFAULT behaves differently on PG10 vs PG11+ — SchemaRisk knows this |
| Safe migration generator | Not just "danger detected" — gives you the exact zero-downtime SQL to run instead |
| Repository impact scanner | Finds which files in your codebase reference the changed tables/columns |
| PR comment reports | Posts a full migration report as a GitHub/GitLab PR comment automatically |
guard mode |
Interactive confirmation gate for dangerous operations before they run |
| Schema drift detection | Compares migration files against a live database to find drift |
| SARIF output | GitHub Security tab integration |
Installation
From crates.io
From source
Binary: target/release/schema-risk
Quick start
# Analyze one migration — know the risk before you deploy
# Use the correct PostgreSQL version for accurate scoring
# Get safe alternatives for everything risky
# Post a full report to your PR
# Guard dangerous operations with typed confirmation
Example output
Terminal (analyze)
SchemaRisk Analysis 202406_add_index.sql
Migration Risk: HIGH (score: 72)
Tables affected: users
Estimated lock duration: ~90 sec
Index rebuild required: YES
Requires maintenance window: YES
Warnings:
! CREATE INDEX on 'users' without CONCURRENTLY will hold a SHARE lock
for the duration of the index build (cols: email)
Recommendations:
CREATE INDEX CONCURRENTLY idx_email ON users(email);
This migration should NOT be deployed without review
Safe Migration Generator (fix)
For a dangerous type change like:
users ALTER COLUMN email TYPE text;
SchemaRisk outputs a complete zero-downtime plan:
-- Step 1: Add shadow column with new type
users ADD COLUMN email_v2 text;
-- Step 2: Back-fill in batches (run until 0 rows updated)
UPDATE users
SET email_v2 = email::text
WHERE email_v2 IS NULL
LIMIT 10000;
-- Step 3: Deploy app to write to both columns
-- Step 4: Atomically swap column names
users RENAME COLUMN email TO email_old;
users RENAME COLUMN email_v2 TO email;
-- Step 5: Drop old column after verifying app health
users DROP COLUMN email_old;
PR Comment Report (ci-report)
When a migration is included in a PR, SchemaRisk automatically posts:
** SchemaRisk — Migration Safety Report (PostgreSQL 14)**
File Risk Score Lock Est. Duration 202406_add_index.sqlHIGH 72 SHARE~90s Safe Alternative:
(email);Impact: 12 files reference
users.email
PostgreSQL version-aware scoring
Pass --pg-version to get accurate risk scores for your specific PostgreSQL version.
| Operation | PG10 | PG11+ |
|---|---|---|
ADD COLUMN DEFAULT |
Full table rewrite | Metadata-only |
SET NOT NULL |
Full scan, long lock | CHECK constraint safe alternative on PG12+ |
ALTER COLUMN TYPE |
Full rewrite (all versions) | Full rewrite (all versions) |
# Score correctly for an older production database
# Or target PG14 (default)
Commands
analyze
Analyze one or more SQL files and report risk.
fix
Apply auto-fixes where supported and show zero-downtime migration plans for everything else.
ci-report
Generate GitHub/GitLab PR comments or JSON CI output.
explain
Show a detailed, statement-by-statement breakdown.
graph
Render the schema dependency graph from migration files.
diff
Compare expected schema (from migrations) against a live database to detect drift.
guard
Intercept dangerous operations and require explicit confirmation before allowing them to run.
# Usage pattern (blocks the migration unless confirmed)
&&
init
Create a starter schema-risk.yml config file.
Automatic PR Migration Reports
Add SchemaRisk to your GitHub Actions workflow and get automatic risk reports on every PR that touches migration files.
Setup (2 minutes)
Copy .github/workflows/schema-risk.yml from this repo into your project, then set PG_VERSION to match your production database:
env:
PG_VERSION: "14" # Set to your production PostgreSQL version
That's it. Every PR with SQL changes will now receive a comment like this:
HIGH RISK — significant impact on database availability.
Review all findings carefully before merging.
File Risk Score Lock Est. Duration Breaking Changes 202406_add_index.sqlHIGH 72 SHARE~90s 3 file(s) Generated by SchemaRisk — Prevent dangerous migrations before they reach production.
Why this matters for your team
When engineers review PRs, they see the risk report. Engineers on other teams ask "what is SchemaRisk?"
Then they install it too.
This is how devtools grow organically — by being useful in the places developers already work.
Guard behavior by actor
| Actor | Detection | Behavior |
|---|---|---|
| Human | Interactive terminal | Shows impact panel and prompts for confirmation |
| CI | CI, GITHUB_ACTIONS, etc. |
Blocks dangerous ops in non-interactive mode |
| Agent | AI provider env indicators | Blocks and emits machine-readable result |
Guard output includes:
- Operation summary
- Risk + lock metadata
- Affected objects
- Likely breakage
- Full audit trail (
.schemarisk-audit.json)
Configuration (schema-risk.yml)
Generate a starter file:
Example:
version: 2
thresholds:
fail_on: high
guard_on: medium
rules:
disabled:
table_overrides:
sessions:
ignored: true
scan:
root_dir: "."
extensions:
exclude:
skip_short_identifiers: true
guard:
require_typed_confirmation: true
audit_log: ".schemarisk-audit.json"
block_agents: true
block_ci: false
output:
format: terminal
color: true
show_recommendations: true
show_impact: true
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success / below configured threshold |
| 1 | Risk meets or exceeds fail threshold |
| 2 | Parse/IO/database command error |
| 3 | Guard runtime error |
| 4 | Guard blocked execution |
Development
License
MIT