You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: switch from AST parsing to alembic upgrade --sql
Replace extract_sql/AST extraction with generate_sql that calls
alembic upgrade --sql for complete DDL generation. This gives squawk
visibility into ORM operations like op.create_index and op.create_table
that were previously invisible.
Extend autocommit checker to flag op.create_index/op.drop_index with
postgresql_concurrently=True outside autocommit_block.
Copy file name to clipboardExpand all lines: README.md
+10-8Lines changed: 10 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,9 @@
2
2
3
3
A [pre-commit](https://pre-commit.com/) hook that lints SQL in [Alembic](https://alembic.sqlalchemy.org/) migrations using [squawk](https://squawkhq.com/), a PostgreSQL migration linter.
4
4
5
-
Squawk operates on raw SQL files, but Alembic migrations are Python. This hook bridges the gap by extracting SQL from `op.execute()` calls in migration files and passing it to squawk for analysis.
5
+
Squawk operates on raw SQL files, but Alembic migrations are Python. This hook bridges the gap by generating DDL via `alembic upgrade --sql` (offline mode) and passing the complete SQL output to squawk for analysis. This captures all SQL statements a migration produces, including ORM operations like `op.create_index()`, `op.create_table()`, and `op.alter_column()`.
6
+
7
+
The hook also checks that concurrent index operations (`CONCURRENTLY` in `op.execute()` or `postgresql_concurrently=True` in `op.create_index()` / `op.drop_index()`) are wrapped in `autocommit_block()`.
6
8
7
9
## Usage
8
10
@@ -11,25 +13,24 @@ Add the following to your `.pre-commit-config.yaml`:
No additional configuration is required. The hook auto-detects your migrations directory by reading `script_location` from `alembic.ini`.
21
+
No additional configuration is required. The hook auto-detects your migrations directory by reading `script_location` from `alembic.ini`. The consumer's `alembic` must be available on PATH (the hook calls it via subprocess).
20
22
21
23
## How It Works
22
24
23
25
When pre-commit runs, the hook:
24
26
25
27
1. Parses `alembic.ini` to find the migrations `versions/` directory
26
28
2. Filters staged files to only those under that directory
27
-
3. Extracts SQL strings from `op.execute()` calls using Python's AST parser
28
-
4. Pipes the extracted SQL to squawk for linting
29
-
30
-
The hook handles common patterns including `op.execute("...")`, `op.execute(sa.text("..."))`, triple-quoted strings, and implicit string concatenation.
29
+
3. Checks for concurrent operations outside `autocommit_block()`
30
+
4. Runs `alembic upgrade --sql` to generate the complete DDL for each migration
31
+
5. Pipes the generated SQL to squawk for linting
31
32
32
-
ORM-level operations like `op.add_column()` and `op.create_table()` are not linted, since they don't contain raw SQL. These produce safe, predictable DDL that squawk is less likely to flag.
33
+
Merge migrations (where `down_revision` is a tuple) are skipped since they produce no DDL.
33
34
34
35
## Squawk Configuration
35
36
@@ -41,6 +42,7 @@ Squawk reads its configuration from `.squawk.toml` in the consumer repo root. Se
0 commit comments