Rule-based linter for SQL migration files. Catches mistakes that make migrations non-idempotent, destructive, or unsafe under concurrent load. Pure Python stdlib — no dependencies.
Supports dialects: generic, postgres, mysql, sqlite.
# Lint a single file
python3 scripts/sql_migration_linter.py lint migrations/001_init.sql
# Lint a directory recursively
python3 scripts/sql_migration_linter.py lint migrations/
# Specify dialect (unlocks Postgres-specific rules)
python3 scripts/sql_migration_linter.py lint migrations/ --dialect postgres
# Filter by minimum severity
python3 scripts/sql_migration_linter.py lint migrations/ --min-severity warning
# JSON output for CI
python3 scripts/sql_migration_linter.py lint migrations/ --format json
# Compact summary
python3 scripts/sql_migration_linter.py lint migrations/ --format summary
# List all rules
python3 scripts/sql_migration_linter.py rules
missing-trailing-semicolon (error) — file does not end with ;mixed-indentation (warning) — tabs and spaces mixed in the same linetrailing-whitespace (info)keyword-case-inconsistent (info) — same keyword appears in mixed casedrop-without-if-exists (warning) — DROP TABLE/INDEX/... without IF EXISTSdestructive-drop-table (warning) — DROP TABLE flagged for reviewcreate-without-if-not-exists (warning) — CREATE TABLE/INDEX/... without IF NOT EXISTScreate-index-locks-table (warning, postgres) — CREATE INDEX without CONCURRENTLYadd-column-not-null-no-default (error, postgres) — ADD COLUMN ... NOT NULL without DEFAULTreserved-word-identifier (warning) — identifier matches a SQL reserved word (e.g. user, order)update-without-where (error)delete-without-where (error)truncate-is-destructive (warning)select-star (info) — SELECT * in migrationsinsert-without-conflict-handling (info) — INSERT without ON CONFLICT / ON DUPLICATE KEYmissing-transaction (warning) — 2+ DDL statements without explicit BEGIN/COMMITbegin-without-commit (error)line:severity: [rule] message, with totals{file, line, rule, severity, message} objects0 — clean (or only info below min-severity)1 — warnings present, no errors2 — errors present# Pre-commit hook — fail on any warning or error
python3 scripts/sql_migration_linter.py lint migrations/ --min-severity warning
# CI gate — fail only on errors
python3 scripts/sql_migration_linter.py lint migrations/ --min-severity error
# Postgres-specific audit
python3 scripts/sql_migration_linter.py lint migrations/ --dialect postgres --format json > report.json
Migrations that look fine locally fail in production because:
CREATE INDEX, ADD COLUMN NOT NULL)UPDATE / DELETE without WHERE)This linter catches those before the PR gets merged.
keyword-case-inconsistent is per-statement, not repo-wide共 1 个版本