Skip to main content

sqlfmt

PyPI Downloads Test

PyPI - Python Version Runs on Linux | MacOS | Windows

sqlfmt formats your dbt SQL files so you don't have to. It is similar in nature to black, gofmt, and rustfmt (but for SQL).

  1. sqlfmt promotes collaboration. An auto-formatter makes it easier to collaborate with your team and solicit contributions from new people. You will never have to mention (or argue about) code style in code reviews again.
  2. sqlfmt is fast. Forget about formatting your code, and spend your time on business logic instead. sqlfmt processes hundreds of files per second and only operates on files that have changed since the last run.
  3. sqlfmt works with Jinja. It formats the code that users look at, and therefore doesn't need to know anything about what happens after the templates are rendered.
  4. sqlfmt integrates with your workflow. As a CLI written in Python, it's easy to install locally on any OS and run in CI. Plays well with dbt, pre-commit, SQLFluff, VSCode, and GitHub Actions. sqlfmt powers the dbt Cloud IDE's Format button.

sqlfmt is not configurable, except for line length. It enforces a single style. sqlfmt maintains comments and some extra newlines, but largely ignores all indentation and line breaks in the input file.

sqlfmt is not a linter. It does not parse your code into an AST; it just lexes it and tracks a small subset of tokens that impact formatting. This lets us "do one thing and do it well:" sqlfmt is very fast, and easier to maintain and extend than linters that need a full SQL grammar.

For now, sqlfmt only works on select, delete, grant, revoke, and create function statements (which is all you need if you use sqlfmt with a dbt project). It is being extended to additional DDL and DML. Visit this tracking issue for more information.

Documentation

Please visit docs.sqlfmt.com for more information on Getting Started, Integrations, the sqlfmt Style, and an API Reference. Or keep reading for an excerpt from the full docs.

Installation

Try it first

Want to test out sqlfmt on a query before you install it? Go to sqlfmt.com to use the interactive, web-based version.

Recommended Installation: Use uv

sqlfmt is a command-line tool that is built in Python and runs on MacOS, Linux, and Windows. It is distributed on PyPI under the name shandy-sqlfmt. There are many ways to install and run it, but we strongly recommend using uv:

  1. Install uv. From a POSIX shell, run:

    curl -LsSf https://astral.sh/uv/install.sh | sh
    

    Or using Windows Powershell:

    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
    
  2. Install sqlfmt as a tool using uv:

    uv tool install "shandy-sqlfmt[jinjafmt]"
    

    This command will install sqlfmt into an isolated environment and add it to your PATH so you can easily run the executable.

    :::tip Depending on your shell and OS, you may need single or double quotes around shandy-sqlfmt[jinjafmt]. :::

  3. Test the installation; run sqlfmt with no arguments:

    sqlfmt
    

    You should see some ASCII art and help text.

:::warning PyPI Names The PyPI distribtuion is shandy-sqlfmt, NOT sqlfmt, which is a different (unrelated but not malicious) package. This is unfortunate, but the author cannot do anything about it. :::

Other Installation Options

  1. Use pip or something pip-like:

    If you know what you’re doing, after installing Python 3.9 or above and activating your virtual environment, install shandy-sqlfmt using pip, pipx, poetry, or any other program that can install Python packages from PyPI:

    pip install "shandy-sqlfmt[jinjafmt]"
    
  2. Use Docker

    You can skip installation altogether and pull the official Docker image instead. See the docs on running sqlfmt in a container.

Using sqlfmt

:::danger Before You Begin sqlfmt may not always produce the formatted output you want. It might even break your SQL syntax. It is highly recommended to only run sqlfmt on files in a version control system (like git), so that it is easy for you to revert any changes made by sqlfmt. On your first run, be sure to make a commit before running sqlfmt.

For more on sqlfmt's maturity see Maturity and Stability. :::

sqlfmt is a command-line tool. It works on any posix terminal and on Windows Powershell. If you have used the Python code formatter Black, the sqlfmt commands will look familiar.

:::tip The code snippets below are commands that can be typed into your terminal, after installing sqlfmt. :::

To list commands and options:

sqlfmt --help

If you want to format all .sql and .sql.jinja files in your current working directory (and all nested directories), simply type (note the trailing ., denoting the current directory):

sqlfmt .

If you don't want to format the files you have on disk, you can use the --check or --diff options. sqlfmt will exit with code 1 if the files on disk are not properly formatted:

sqlfmt --check .
sqlfmt --diff .

sqlfmt can also format code passed through standard input (stdin) by passing - as the files argument. The formatted code will be output to stdout (all other output from sqlfmt is routed to stderr):

echo "select 1" | sqlfmt -

Configuring sqlfmt using pyproject.toml

Any command-line option for sqlfmt can also be set in a pyproject.toml file, under a [tool.sqlfmt] section header. Options passed at the command line will override the settings in the config file. See the docs for more information.

The jinjafmt extra

sqlfmt loves properly-formatted jinja, too.

See the docs for more information about using the jinjafmt extra or disabling jinja formatting.

Using sqlfmt with different SQL dialects

sqlfmt's rules are simple, which means it does not have to parse every single token in your query. This allows nearly all SQL dialects to be formatted using sqlfmt's default "polyglot" dialect, which requires no configuration.

The exception to this is ClickHouse, which is case-sensitive where other dialects are not. To prevent the lowercasing of function names, database identifiers, and aliases, use the --dialect clickhouse option when running sqlfmt. For example,

$ sqlfmt . --dialect clickhouse

This can also be configured using the pyproject.toml file:

[tool.sqlfmt]
dialect = "clickhouse"

Note that with this option, sqlfmt will not lowercase most non-reserved keywords, even common ones like sum or count. See (and please join) this discussion for more on this topic.

Integrations

sqlfmt plays nicely with other analytics engineering tools. For more information, see the docs.

dbt

sqlfmt was built for dbt, so only minimal configuration is required. We recommend excluding your target and dbt_packages directories from formatting. You can do this with the command-line --exclude option, or by setting exclude in your pyproject.toml file:

[tool.sqlfmt]
exclude=["target/**/*", "dbt_packages/**/*"]

Other Integrations

Config for other integrations is detailed in the docs linked below:

The sqlfmt style

The only thing you can configure with sqlfmt is the desired line length of the formatted file. You can do this with the --line-length or -l options. The default is 88.

sqlfmt borrows elements from well-accepted styles from other programming languages. It places opening brackets on the same line as preceding function names (like black for python and 1TBS for C). It indents closing brackets to the same depth as the opening bracket (this is extended to statements that must be closed, like case and end).

The sqlfmt style is as simple as possible, with little-to-no special-casing of formatting concerns. While at first blush, this may not create a format that is as "nice" or "expressive" as hand-crafted indentation, over time, as you grow accustomed to the style, formatting becomes transparent and the consistency will allow you to jump between files, projects, and even companies much faster.

Read More

Why lowercase?

Because SQL is code! But there are other good reasons too.

Why trailing commas?

Using trailing commas follows the convention of every other written language and programming language. But wait, there's more.

Contributing

Code style: black Checked with mypy Maintainability Test Coverage

Providing Feedback

We'd love to hear from you! Open an Issue to request new features, report bad formatting, or say hello.

Setting up Your Dev Environment and Running Tests

  1. Install uv You may also need or want make.
  2. Clone this repo into a directory (let's call it sqlfmt), then cd sqlfmt.
  3. Use uv sync --all-groups --all-extras to install the project (editable) and its dependencies (including the jinjafmt and sqlfmt_primer extras) into a new virtual env.
  4. Type make to run all tests and linters, or run pytest, ruff, and mypy individually, using uv (e.g., uv run pytest).

Updating primer repos to reflect formatting changes

  1. Make sure all changes are committed to sqlfmt.
  2. Check out main in the repo and make sure you pull changes locally.
  3. Check out the unformatted tag in the repo with git checkout -b chore/apply-abc123 unformatted where abc123 is the hash of the most recent sqlfmt commit (from 1).
  4. Run sqlfmt against the working tree, then git add . and git commit -m "chore: apply sqlfmt abc123".
  5. We will have conflicts with main that we want to ignore, so merge main into this branch, ignoring anything on main: git merge -s ours main.
  6. Push and open a PR; squash and merge. Grab the commit SHA.
  7. Paste the commit SHA as a ref into primer.py.
  8. Run sqlfmt_primer -k to clear the cache, then update the stats in primer.py to match the results.

Metadata

Release files for shandy-sqlfmt 0.32.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for shandy-sqlfmt 0.32.0
File Size Uploaded
shandy_sqlfmt-0.32.0.tar.gz 72.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for shandy-sqlfmt 0.32.0
File Interpreter ABI Platform
shandy_sqlfmt-0.32.0-py3-none-any.whl Python 3 none any Details

Total release size: 144.9 kB

Release files / shandy_sqlfmt-0.32.0.tar.gz

Download URL shandy_sqlfmt-0.32.0.tar.gz
Size 72.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f1e93928659f8159e399f189050b60dbe2135812eccfc1566b04644fb0dc3304
BLAKE2b-256 checksum
How to use checksums
186129e13aa8c39da9fe821fb393c4113b166517a38d8a2bb53142c9b6dd0892
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.

Transparency log

Release files / shandy_sqlfmt-0.32.0-py3-none-any.whl

Download URL shandy_sqlfmt-0.32.0-py3-none-any.whl
Size 72.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
716cfa4910c318a7b905002f73c95a0ef6bdc4a23e79b6fa2ad1c0f6aab3ee46
BLAKE2b-256 checksum
How to use checksums
a4c7336524d9e60d670c493a034b2c53ea3cefffb55ab7cc0248f8377f1b9a97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.32.0 This release

2 release files

0.29.0

2 release files

0.28.2

2 release files

0.28.1

2 release files

0.28.0

2 release files

0.27.0

2 release files

0.26.0

2 release files

0.25.0

2 release files

0.24.0

2 release files

0.23.3

2 release files

0.23.2

2 release files

0.23.1

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.21.3

2 release files

0.21.2

2 release files

0.21.1

2 release files

0.21.0

2 release files

0.20.0

2 release files

0.19.2

2 release files

0.19.1

2 release files

0.18.3

2 release files

0.18.2

2 release files

0.18.1

2 release files

0.18.0

2 release files

0.17.1

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.2

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.14.2

2 release files

0.14.0

2 release files

0.12.0

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page