dfmt
An SQL formatter that actually parses your SQL — full grammar, full AST, one per dialect — and formats dbt models without pretending Jinja is a comment.
curl -fsSL https://dfmt.datoria.ai/install.sh | sh
cd your-project
dfmt # the first time, sets the project up; after that, says what would change
dfmt diff # see what would change
dfmt write # format every file in place
dfmt check # exit 1 if anything is unformatted (for CI)
dfmt setup # tune the formatting, live on your own files
On Windows, install from PowerShell with irm https://dfmt.datoria.ai/install.ps1 | iex. dfmt is
free and needs no account.
What makes it different
It knows the dialect. dfmt shares its parser with Datoria's lineage and type-inference tools:
one grammar per dialect, generated into a real parser, not a token-level pattern matcher. QUALIFY
in Snowflake, pipe syntax in BigQuery, SETTINGS in ClickHouse — these are grammar, so they format
like grammar rather than like unfamiliar text to be stepped around.
It handles Jinja for real. A dbt model is a template that becomes SQL. dfmt evaluates the
template with its own Jinja engine, lays out the SQL that results, and puts every {{ ref() }} and
{% if %} back where it belongs — no regexes, no "format the compiled output and hand it back", no
{# fmt: off #} around anything with a tag in it.
It refuses to guess. dfmt will not pick a dialect for you, and it will not format a template as if it were plain SQL. Both are the same mistake: a recovering parser accepts almost anything, so a wrong guess does not fail — it quietly produces something that reads fine and means something else. When dfmt cannot tell, it says so and leaves the file alone.
It does not lose your SQL. Every run verifies that the output holds the same tokens, in the same order, as the input. Formatting moves whitespace; it does not edit your query.
Where to go next
- Install: the supported platforms, where dfmt goes, upgrading and uninstalling.
- Getting Started: set a project up, format it, and tune the result.
- CLI Reference: every command and exit code.
- Configuration Reference: every
dlab.jsonoption, generated from the source. - dbt Integration: models, macros, and what dfmt does with Jinja.
- Runners: what reads each file (dbt, Flyway, psql, SQL*Plus, Qlik and the rest), and how dfmt picks one.
- CI Integration:
dfmt checkin a pipeline. - Editors: format on save in VS Code, and in any editor with a language-server client.
- Options: the walk-through, one page per option in the order they depend on each other, each with examples that are themselves tests and can be replayed on the page.
- Jinja Examples: an appendix of real before→after templates, grouped by construct.