Skip to main content

Linter for PostgreSQL migrations

Project description

squawk npm

Linter for Postgres migrations & SQL

Quick Start | Playground | Rules Documentation | GitHub Action | DIY GitHub Integration

Why?

Prevent unexpected downtime caused by database migrations and encourage best practices around Postgres schemas and SQL.

Install

npm install -g squawk-cli

# or via PYPI
pip install squawk-cli

# or install binaries directly via the releases page
https://github.com/sbdchd/squawk/releases

Or via Docker

You can also run Squawk using Docker. The official image is available on GitHub Container Registry.

# Assuming you want to check sql files in the current directory
docker run --rm -v $(pwd):/data ghcr.io/sbdchd/squawk:latest *.sql

Or via the Playground

Use the WASM powered playground to check your SQL locally in the browser!

https://play.squawkhq.com

Or via VSCode

https://marketplace.visualstudio.com/items?itemName=sbdchd.squawk

Usage

 squawk example.sql
warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit.
  ╭▸ example.sql:6:10
  6      "id" serial NOT NULL PRIMARY KEY,
            ━━━━━━
     help: Use 64-bit integer values instead to prevent hitting this limit.
  ╭╴
6      "id" bigserial NOT NULL PRIMARY KEY,
  ╰╴         +++
warning[prefer-identity]: Serial types make schema, dependency, and permission management difficult.
  ╭▸ example.sql:6:10
  6      "id" serial NOT NULL PRIMARY KEY,
            ━━━━━━
     help: Use an `IDENTITY` column instead.
  ╭╴
6 -     "id" serial NOT NULL PRIMARY KEY,
6 +     "id" integer generated by default as identity NOT NULL PRIMARY KEY,
  ╰╴
warning[prefer-text-field]: Changing the size of a `varchar` field requires an `ACCESS EXCLUSIVE` lock, that will prevent all reads and writes to the table.
  ╭▸ example.sql:7:13
  7      "alpha" varchar(100) NOT NULL
               ━━━━━━━━━━━━
     help: Use a `TEXT` field with a `CHECK` constraint.
  ╭╴
7 -     "alpha" varchar(100) NOT NULL
7 +     "alpha" text NOT NULL
  ╰╴
warning[require-concurrent-index-creation]: During normal index creation, table updates are blocked, but reads are still allowed.
   ╭▸ example.sql:10:1
   10  CREATE INDEX "field_name_idx" ON "table_name" ("field_name");
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
       help: Use `concurrently` to avoid blocking writes.
   ╭╴
10  CREATE INDEX concurrently "field_name_idx" ON "table_name" ("field_name");
   ╰╴             ++++++++++++
warning[constraint-missing-not-valid]: By default new constraints require a table scan and block writes to the table while that scan occurs.
   ╭▸ example.sql:12:24
   12  ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
       help: Use `NOT VALID` with a later `VALIDATE CONSTRAINT` call.
warning[disallowed-unique-constraint]: Adding a `UNIQUE` constraint requires an `ACCESS EXCLUSIVE` lock which blocks reads and writes to the table while the index is built.
   ╭▸ example.sql:12:28
   12  ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
       help: Create an index `CONCURRENTLY` and create the constraint using the index.

Find detailed examples and solutions for each rule at https://squawkhq.com/docs/rules
Found 6 issues in 1 file (checked 1 source file)

squawk --help

squawk
Find problems in your SQL

USAGE:
    squawk [FLAGS] [OPTIONS] [path]... [SUBCOMMAND]

FLAGS:
        --assume-in-transaction
            Assume that a transaction will wrap each SQL file when run by a migration tool

            Use --no-assume-in-transaction to override this setting in any config file that exists
    -h, --help
            Prints help information

    -V, --version
            Prints version information

        --verbose
            Enable debug logging output


OPTIONS:
    -c, --config <config-path>
            Path to the squawk config file (.squawk.toml)

        --debug <format>
            Output debug info [possible values: Lex, Parse]

        --exclude-path <excluded-path>...
            Paths to exclude

            For example: --exclude-path=005_user_ids.sql --exclude-path=009_account_emails.sql

            --exclude-path='*user_ids.sql'

    -e, --exclude <rule>...
            Exclude specific warnings

            For example: --exclude=require-concurrent-index-creation,ban-drop-database

        --pg-version <pg-version>
            Specify postgres version

            For example: --pg-version=13.0
        --reporter <reporter>
            Style of error reporting [possible values: Tty, Gcc, Json]

        --stdin-filepath <filepath>
            Path to use in reporting for stdin


ARGS:
    <path>...
            Paths to search


SUBCOMMANDS:
    help                Prints this message or the help of the given subcommand(s)
    upload-to-github    Comment on a PR with Squawk's results

Rules

Individual rules can be disabled via the --exclude flag

squawk --exclude=adding-field-with-default,disallowed-unique-constraint example.sql

Disabling rules via comments

Rule violations can be ignored via the squawk-ignore comment:

-- squawk-ignore ban-drop-column
alter table t drop column c cascade;

You can also ignore multiple rules by making a comma seperated list:

-- squawk-ignore ban-drop-column, renaming-column,ban-drop-database
alter table t drop column c cascade;

To ignore a rule for the entire file, use squawk-ignore-file:

-- squawk-ignore-file ban-drop-column
alter table t drop column c cascade;
-- also ignored!
alter table t drop column d cascade;

Or leave off the rule names to ignore all rules for the file

-- squawk-ignore-file
alter table t drop column c cascade;
create table t (a int);

Configuration file

Rules can also be disabled with a configuration file.

By default, Squawk will traverse up from the current directory to find a .squawk.toml configuration file. You may specify a custom path with the -c or --config flag.

squawk --config=~/.squawk.toml example.sql

The --exclude flag will always be prioritized over the configuration file.

Example .squawk.toml

excluded_rules = [
    "require-concurrent-index-creation",
    "require-concurrent-index-deletion",
]

See the Squawk website for documentation on each rule with examples and reasoning.

Bot Setup

Squawk works as a CLI tool but can also create comments on GitHub Pull Requests using the upload-to-github subcommand.

Here's an example comment created by squawk using the example.sql in the repo:

https://github.com/sbdchd/squawk/pull/14#issuecomment-647009446

See the "GitHub Integration" docs for more information.

pre-commit hook

Integrate Squawk into Git workflow with pre-commit. Add the following to your project's .pre-commit-config.yaml:

repos:
  - repo: https://github.com/sbdchd/squawk
    rev: 2.47.0
    hooks:
      - id: squawk
        files: path/to/postgres/migrations/written/in/sql

Note the files parameter as it specifies the location of the files to be linted.

Prior Art / Related

Related Blog Posts / SE Posts / PG Docs

Dev

cargo install
cargo run
./s/test
./s/lint
./s/fmt

... or with nix:

$ nix develop
[nix-shell]$ cargo run
[nix-shell]$ cargo insta review
[nix-shell]$ ./s/test
[nix-shell]$ ./s/lint
[nix-shell]$ ./s/fmt

Adding a New Rule

When adding a new rule, running cargo xtask new-rule will create stubs for your rule in the Rust crate and in Documentation site.

cargo xtask new-rule 'prefer big serial'

Releasing a New Version

  1. Run s/update-version

    # update version in squawk/Cargo.toml, package.json, flake.nix to 4.5.3
    s/update-version 4.5.3
    
  2. Update the CHANGELOG.md

    Include a description of any fixes / additions. Make sure to include the PR numbers and credit the authors.

  3. Create a new release on GitHub

    Use the text and version from the CHANGELOG.md

Algolia

The squawkhq.com Algolia index can be found on the crawler website. Algolia reindexes the site every day at 5:30 (UTC).

How it Works

Squawk uses its parser (based on rust-analyzer's parser) to create a CST. The linters then use an AST layered on top of the CST to navigate and record warnings, which are then pretty printed!

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

squawk_cli-2.47.0.tar.gz (777.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

squawk_cli-2.47.0-py3-none-win_amd64.whl (4.0 MB view details)

Uploaded Python 3Windows x86-64

squawk_cli-2.47.0-py3-none-win32.whl (3.7 MB view details)

Uploaded Python 3Windows x86

squawk_cli-2.47.0-py3-none-manylinux_2_28_x86_64.whl (6.7 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

squawk_cli-2.47.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (5.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

squawk_cli-2.47.0-py3-none-macosx_11_0_arm64.whl (4.4 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

squawk_cli-2.47.0-py3-none-macosx_10_12_x86_64.whl (4.6 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file squawk_cli-2.47.0.tar.gz.

File metadata

  • Download URL: squawk_cli-2.47.0.tar.gz
  • Upload date:
  • Size: 777.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.13.1

File hashes

Hashes for squawk_cli-2.47.0.tar.gz
Algorithm Hash digest
SHA256 0155276652892caf31d911b70bb6d5d2bce4b6da217a30ad5ab3b985f8bdcbb1
MD5 811fb6775934006c64d2a68954ec0f56
BLAKE2b-256 bb94350c78370ff995a0b317d1b828ae371060be94f2fd52ed098a0447296cfc

See more details on using hashes here.

File details

Details for the file squawk_cli-2.47.0-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for squawk_cli-2.47.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 a81914f2a5883ed122429e1b7851a8066dfb3ab3a435c3e3ab14886efa2f1bb4
MD5 89a1589a2fe0336e27f6181ba7a04ef5
BLAKE2b-256 0c8d916cb2309be15cbbae2f933579058deb3ca91bb85f68af5a38197265c6e0

See more details on using hashes here.

File details

Details for the file squawk_cli-2.47.0-py3-none-win32.whl.

File metadata

  • Download URL: squawk_cli-2.47.0-py3-none-win32.whl
  • Upload date:
  • Size: 3.7 MB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.13.1

File hashes

Hashes for squawk_cli-2.47.0-py3-none-win32.whl
Algorithm Hash digest
SHA256 7276ba129a1a3638e2f3c398aa040ef41f0eb3badfce5b88a288e9fed9dddde6
MD5 452a6756ad77599853fb28030ddb6418
BLAKE2b-256 ebb62fd4ae56f21f3304ac64d133b5969d9f9b4a85507eb85fb05f0a20e27540

See more details on using hashes here.

File details

Details for the file squawk_cli-2.47.0-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for squawk_cli-2.47.0-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a6a7df681f199488d5eb5d206e1d9bb0913c3b1ac0870d0b543af5f58bc7a757
MD5 ca0b9b0c72230132a9a03d4cad9fa180
BLAKE2b-256 b2f621b7828f499018e78f324d9dd9e7f501644d712129d00d07a1a1105cac32

See more details on using hashes here.

File details

Details for the file squawk_cli-2.47.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for squawk_cli-2.47.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f4e798501d9f662ef92e4104d5cf270c0a9bcf23cd2a3a81e7c645750ae78b9f
MD5 214db7b8e047ad81cc7ada203c7a4606
BLAKE2b-256 a48d2f82c0fc069730acf8ab83c975943046fbfb357d6c9bb073fd55fb927fb9

See more details on using hashes here.

File details

Details for the file squawk_cli-2.47.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for squawk_cli-2.47.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 66328e2ad5a9714966d15f069a98e71218fb77c6dfb3cea0a908b451c2304be5
MD5 1b8f3e4d47558f31af066c2a7c674cba
BLAKE2b-256 216683d1b7ab6e7fc2ea14cdfb9dad2d2e7727ec50d1ec72c6c5a6a55a7fb53a

See more details on using hashes here.

File details

Details for the file squawk_cli-2.47.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for squawk_cli-2.47.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 34d5c7bfb1098a34f344996855ba43f4b06f27473bc444b65e54d93f6e03a8f3
MD5 d2218154cc9ac9b12f338b3bbba856fd
BLAKE2b-256 d6d8ea223bd56b34dc40120ef63a3bea0683b603c6b8e081255572c6a386fcca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page