Skip to main content

dfmt

A SQL formatter that parses your SQL properly — full grammar, full AST, per dialect — and formats dbt models without pretending Jinja is a comment.

dfmt init postgres   # record the dialect
dfmt diff . # see what would change
dfmt write . # format
dfmt check . # exit 1 if anything is unformatted

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 left alone.

It handles Jinja for real. A dbt model is a template that becomes SQL. dfmt evaluates the template, formats the resulting SQL, 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 SQL. Both are the same mistake: a recovering parser accepts almost anything, so a wrong guess does not fail — it silently 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