SQL Migration Lock Check · comparison
If you have searched for a PostgreSQL migration linter, you have found squawk. It is the established answer, and this page exists because pretending otherwise would waste your time. Here is what each tool is actually built to do — and, below, an explicit note on what this page is not.
squawk parses SQL with a real PostgreSQL parser and reports per-statement rules, with editor and CI integration and a maintained rule set.
This checker scans statements textually, and its distinguishing checks are relational — about one statement in the context of another:
lock_timeout. Whether an exclusive-lock statement is protected depends on whether a SET lock_timeout appears above it in the file. This is the check that matters most in practice, because it is the difference between a migration that fails harmlessly and one that stalls every query on the table.NOT VALID and VALIDATE CONSTRAINT in one transaction. Both statements are individually correct and idiomatic. Together inside one BEGIN block they hold the lock for the whole validation anyway, so the two-step split — the entire point of writing it that way — buys nothing.CREATE INDEX CONCURRENTLY inside a transaction block. Not a style problem: PostgreSQL refuses it outright at runtime. Since most migration frameworks wrap each file in a transaction by default, this is how a correct concurrency fix most often fails.SET NOT NULL with a validated CHECK to lean on. On PostgreSQL 12+ this is either a cheap metadata change or a full table scan under an exclusive lock, and which one depends entirely on whether something earlier in the file added the constraint.A per-statement rule engine cannot answer any of those from the statement alone. That is the wedge — not a claim that it finds more, but that these four are a different shape of question.
| SQL Migration Lock Check | squawk | |
|---|---|---|
| Install | None for the browser tool; three files and Node 18+ for the CLI | A binary or package to install |
| Parsing | Textual statement scanner (handles comments, dollar-quoting, transaction blocks) | Real PostgreSQL parser |
| Emphasis | Relational checks: lock queue exposure, transaction grouping, the fast paths | Per-statement rules across a broad, maintained set |
| Editor integration | No | Yes |
| Runs in a browser | Yes — paste and read, nothing uploaded | No |
| Database access | None, by construction | None required |
When you want a maintained, widely-used linter with a real parser, editor integration, and a rule set more people have exercised than this one. A real parser is genuinely better than text scanning on unusual SQL — deeply nested expressions, exotic syntax, dialect edge cases — and if you are standardising migration linting across a team, established tooling with a community around it is worth more than any single clever check.
Install it. The two are not exclusive, and they disagree about very little. Use this one when you want an answer in ten seconds without installing anything, when you want the four relational checks above, or when the person who needs to understand the finding is not the person who set up the linter.
No. Nothing here is measured against squawk — no rule-count comparison, no timing, no accuracy claim, and no run of squawk was performed to produce this page. It describes what each tool is built to do, based on each project's own stated purpose. If a specific claim on this page is out of date or wrong, it is a bug in this page.
No. This project is not affiliated with, endorsed by, or connected to squawk or its maintainers in any way. squawk is named here because it is what a practitioner searching for this has probably already found.