Linter for dangerous Postgres migration patterns in Diesel and SQLx. Prevents downtime caused by unsafe schema changes.
✓ Detects operations that lock tables or cause downtime
✓ Provides safe alternatives for each blocking operation
✓ Works with both Diesel and SQLx migration frameworks
✓ Supports safety-assured blocks for verified operations
✓ Extensible with custom checks
Uses PostgreSQL's own parser. diesel-guard embeds libpg_query — the C library compiled into Postgres itself. What diesel-guard flags is exactly what Postgres sees. If your SQL has a syntax error, diesel-guard reports that too.
Scriptable custom checks. Write project-specific rules in Rhai with full access to the SQL AST. No forking required.
Version-aware. Configure postgres_version to suppress checks that don't apply
to your version (e.g., constant defaults are safe on PG 11+).
No database connection required. Works on SQL files directly — no running Postgres instance needed in CI.
Via Cargo:
cargo install diesel-guardVia Homebrew:
brew install ayarotsky/tap/diesel-guardVia shell script (macOS/Linux):
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/ayarotsky/diesel-guard/releases/latest/download/diesel-guard-installer.sh | shVia PowerShell (Windows):
powershell -ExecutionPolicy Bypass -c "irm https://github.com/ayarotsky/diesel-guard/releases/latest/download/diesel-guard-installer.ps1 | iex"diesel-guard init # creates diesel-guard.toml
diesel-guard check # checks ./migrations/ by defaultWhen it finds an unsafe migration:
❌ Unsafe migration detected in migrations/20240101_add_admin/up.sql
❌ ADD COLUMN with DEFAULT
Problem:
Adding column 'admin' with DEFAULT on table 'users' requires a full table
rewrite on Postgres < 11, acquiring an ACCESS EXCLUSIVE lock.
Safe alternative:
1. Add the column without a default:
ALTER TABLE users ADD COLUMN admin BOOLEAN;
2. Backfill data in batches (outside migration):
UPDATE users SET admin = false WHERE admin IS NULL;
3. Add default for new rows only:
ALTER TABLE users ALTER COLUMN admin SET DEFAULT false;
Add to your GitHub Actions workflow:
- uses: ayarotsky/diesel-guard-action@v124 built-in checks across locking, rewrites, and schema safety:
| Check | Risk |
|---|---|
| ADD COLUMN with DEFAULT | Table rewrite on Postgres < 11 (ACCESS EXCLUSIVE) |
| ADD INDEX without CONCURRENTLY | Blocks writes (SHARE lock) |
| ADD NOT NULL constraint | Full table scan (ACCESS EXCLUSIVE) |
| ADD PRIMARY KEY | Blocks all operations during index creation |
| ADD UNIQUE constraint | ACCESS EXCLUSIVE during index build |
| ALTER COLUMN TYPE | Table rewrite (ACCESS EXCLUSIVE) |
| ADD COLUMN with SERIAL | Table rewrite to populate sequence |
| ADD COLUMN with GENERATED STORED | Table rewrite to compute expressions |
| DROP COLUMN | ACCESS EXCLUSIVE lock |
| DROP INDEX without CONCURRENTLY | ACCESS EXCLUSIVE lock |
| DROP PRIMARY KEY | Breaks FK relationships |
| DROP TABLE | Irreversible, ACCESS EXCLUSIVE |
| DROP DATABASE | Irreversible |
| REINDEX without CONCURRENTLY | ACCESS EXCLUSIVE lock |
| RENAME COLUMN | Breaks running app references immediately |
| RENAME TABLE | Breaks running app references, ACCESS EXCLUSIVE |
| TRUNCATE TABLE | ACCESS EXCLUSIVE, cannot be batched |
| ADD COLUMN with JSON | Breaks DISTINCT/GROUP BY |
| ADD COLUMN with CHAR | Storage waste, comparison bugs |
| ADD COLUMN with TIMESTAMP | DST/timezone hazards |
| PRIMARY KEY with INT/SMALLINT | ID exhaustion risk |
| CREATE EXTENSION | Requires superuser |
| CONSTRAINT without name | Auto-names break future migrations |
| CREATE INDEX with 4+ columns | Ineffective, high storage overhead |
Plus custom checks via Rhai scripting.
When you've reviewed an operation and confirmed it's safe, wrap it in a safety-assured block to suppress the check:
-- safety-assured:start
ALTER TABLE users DROP COLUMN legacy_field;
-- safety-assured:end- Your Diesel Migrations Might Be Ticking Time Bombs
- Zero-downtime Postgres migrations: the hard parts
- Zero-downtime Postgres migrations: a little help
- Seven tips for dealing with Postgres locks
- Move fast and migrate things: how we automated migrations in Postgres
- PostgreSQL at scale: database schema changes without downtime
- SQL Style Guide
Inspired by strong_migrations by Andrew Kane.
If this looks useful, a star helps more developers find it ⭐
