sqlfmt
sqlfmt 为你的 dbt SQL 文件进行格式化,让你无需操心。它在性质上类似于 black、gofmt 和 rustfmt(但针对 SQL)。
- sqlfmt 促进协作。 自动格式化工具使与团队协作以及征求新成员的贡献变得更加容易。你再也不必在代码审查中提及(或争论)代码风格。
- sqlfmt 速度快。 忘掉代码格式化,把时间花在业务逻辑上。sqlfmt 每秒处理数百个文件,并且只处理自上次运行以来发生更改的文件。
- sqlfmt 支持 Jinja。 它格式化用户查看的代码,因此无需了解模板渲染后发生的情况。
- sqlfmt 与你的工作流集成。 作为一个用 Python 编写的 CLI,它很容易在任何操作系统上本地安装并在 CI 中运行。与 dbt、pre-commit、SQLFluff、VSCode 和 GitHub Actions 配合良好。sqlfmt 为 dbt Cloud IDE 的 Format 按钮提供支持。
sqlfmt 不可配置,除了行长度。它强制使用单一风格。sqlfmt 保留注释和一些额外的换行符,但基本上忽略输入文件中的所有缩进和换行。
sqlfmt 不是 linter。它不会将你的代码解析为 AST;它只是对其进行词法分析并跟踪影响格式化的一小部分 token。这让我们能够“做好一件事并把它做好”:sqlfmt 非常快,并且比需要完整 SQL 语法的 linter 更容易维护和扩展。
目前,sqlfmt 仅支持 select、delete、grant、revoke 和 create function 语句(如果你使用 sqlfmt 配合 dbt 项目,这些就足够了)。它正在扩展以支持更多的 DDL 和 DML。请访问 此跟踪问题 以获取更多信息。
文档
请访问 docs.sqlfmt.com 以获取有关入门指南、集成、sqlfmt 样式以及 API 参考的更多信息。或者继续阅读以查看完整文档的摘录。
安装
先试用
想在安装之前测试 sqlfmt 处理查询吗?前往 sqlfmt.com 使用交互式网页版本。
推荐安装方式:使用 uv
sqlfmt 是一个用 Python 构建的命令行工具,可在 MacOS、Linux 和 Windows 上运行。它以 shandy-sqlfmt 的名称发布在 PyPI 上。有许多安装和运行它的方法,但我们强烈
推荐使用 uv:
-
安装 uv。在 POSIX shell 中,运行:
curl -LsSf https://astral.sh/uv/install.sh | sh
或者使用 Windows Powershell:
```pwsh
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
2. 使用 uv 将 sqlfmt 安装为工具:
```bash
uv tool install "shandy-sqlfmt[jinjafmt]"
```
此命令会将 sqlfmt 安装到隔离环境中,并将其添加到您的 PATH 中,以便您可以轻松运行可执行文件。
:::tip
根据您的 shell 和操作系统,您可能需要在 `shandy-sqlfmt[jinjafmt]` 周围使用单引号或双引号。
:::
3. 测试安装;不带参数运行 sqlfmt:
```bash
sqlfmt
```
你应该会看到一些 ASCII 艺术和帮助文本。
:::warning PyPI 名称
PyPI 发行版是 shandy-sqlfmt,而不是 sqlfmt,后者是一个不同的(无关但并非恶意)软件包。
这很遗憾,但作者对此无能为力。
:::
其他安装选项
-
使用 pip 或类似 pip 的工具:
如果你知道自己在做什么,在安装 Python 3.9 或更高版本并激活虚拟环境后,使用 pip、pipx、poetry 或任何其他可以从 PyPI 安装 Python 软件包的程序安装
shandy-sqlfmt:pip install "shandy-sqlfmt[jinjafmt]" -
使用 Docker
您可以完全跳过安装步骤,改为拉取官方 Docker 镜像。请参阅在容器中运行 sqlfmt 的文档。
使用 sqlfmt
:::danger 开始之前 sqlfmt 并不总能生成您期望的格式化输出。 它甚至可能破坏您的 SQL 语法。强烈建议仅在版本控制系统(如 git)中的文件上运行 sqlfmt,以便轻松还原 sqlfmt 所做的任何更改。在首次运行时,请务必在运行 sqlfmt 之前进行一次提交。
有关 sqlfmt 成熟度的更多信息,请参阅成熟度与稳定性。 :::
sqlfmt 是一个命令行工具。它适用于任何 posix 终端以及 Windows Powershell。如果您使用过 Python 代码格式化工具 Black,那么 sqlfmt 的命令会让您感到熟悉。
:::tip 以下代码片段是安装 sqlfmt 后可以在终端中输入的命令。 :::
要列出命令和选项:
sqlfmt --help
如果您想格式化当前工作目录(以及所有嵌套目录)中的所有 .sql 和 .sql.jinja 文件,只需输入(注意末尾的 .,表示当前目录):
sqlfmt .
如果你不想格式化磁盘上的文件,可以使用 --check 或 --diff 选项。如果磁盘上的文件格式不正确,sqlfmt 将以代码 1 退出:
sqlfmt --check .
sqlfmt --diff .
sqlfmt 还可以通过标准输入(stdin)格式化代码,方法是将 - 作为文件参数传入。格式化后的代码将输出到 stdout(sqlfmt 的所有其他输出均路由到 stderr):
echo "select 1" | sqlfmt -
使用 pyproject.toml 配置 sqlfmt
sqlfmt 的任何命令行选项都可以在 pyproject.toml 文件中的 [tool.sqlfmt] 部分标题下设置。在命令行传递的选项将覆盖配置文件中的设置。请参阅文档以获取更多信息。
jinjafmt 附加组件
sqlfmt 同样喜欢格式规范的 jinja。
请参阅文档以获取有关使用 jinjafmt 附加组件或禁用 jinja 格式化的更多信息。
使用 sqlfmt 处理不同的 SQL 方言
sqlfmt 的规则很简单,这意味着它不需要解析查询中的每一个 token。这使得几乎所有 SQL 方言都可以使用 sqlfmt 的默认 "polyglot" 方言进行格式化,且无需任何配置。
例外是 ClickHouse,它在其他方言不区分大小写的地方是区分大小写的。为了防止函数名、数据库标识符和别名被转换为小写,在运行 sqlfmt 时使用 --dialect clickhouse 选项。例如,
$ sqlfmt . --dialect clickhouse
这也可以通过 pyproject.toml 文件进行配置:
[tool.sqlfmt]
dialect = "clickhouse"
请注意,使用此选项时,sqlfmt 不会将大多数非保留关键字转换为小写,即使是像 sum 或 count 这样常见的关键字。有关此主题的更多信息,请参阅(并欢迎加入)此讨论。
集成
sqlfmt 与其他分析工程工具配合良好。有关更多信息,请参阅文档。
dbt
sqlfmt 专为 dbt 构建,因此只需最小配置。我们建议将 target 和 dbt_packages 目录排除在格式化之外。您可以通过命令行 --exclude 选项,或在 pyproject.toml 文件中设置 exclude 来实现:
[tool.sqlfmt]
exclude=["target/**/*", "dbt_packages/**/*"]
其他集成
其他集成的配置详情见下方链接中的文档:
sqlfmt 风格
sqlfmt 中唯一可配置的是格式化文件的期望行长度。您可以通过 --line-length 或 -l 选项来实现。默认值为 88。
sqlfmt 借鉴了其他编程语言中广为人知的风格元素。它将开括号放在前导函数名的同一行(类似于 python 的 black 和 C 的 1TBS)。它将闭括号缩进到与开括号相同的深度(这扩展到了必须闭合的语句,如 case 和 end)。
sqlfmt 风格尽可能简单,几乎没有对格式问题的特殊处理。乍一看,这可能不会创建出像手工制作的缩进那样“美观”或“富有表现力”的格式,但随着时间的推移,当您逐渐习惯这种风格时,格式化会变得透明,一致性将允许您在文件、项目甚至公司之间更快地切换。
为什么使用小写?
因为 SQL 是代码!但还有其他好的理由。
为什么使用尾随逗号?
使用尾随逗号遵循了所有其他书面语言和编程语言的惯例。但等等,还有更多。
贡献
提供反馈
我们非常乐意听取您的意见!打开一个 Issue 以请求新功能、报告格式问题或打个招呼。
设置开发环境并运行测试
- 安装 uv 您可能还需要或想要 make。
- 将此仓库克隆到一个目录(我们称之为
sqlfmt),然后cd sqlfmt。 - 使用
uv sync --all-groups --all-extras将项目(可编辑模式)及其依赖项(包括jinjafmt和sqlfmt_primer额外组件)安装到一个新的虚拟环境中。 - 输入
make以运行所有测试和 linter,或者分别运行pytest、ruff和mypy,使用uv(例如,uv run pytest)。
更新 primer 仓库以反映格式变更
- 确保所有更改已提交到 sqlfmt。
- 在仓库中检出
main,并确保您pull本地更改。 - 使用
git checkout -b chore/apply-abc123 unformatted在仓库中检出unformatted标签,其中abc123是最近的 sqlfmt 提交的哈希值(来自 1)。 - 对工作树运行 sqlfmt,然后
git add .和git commit -m "chore: apply sqlfmt abc123"。 - 我们将与 main 产生冲突,我们希望忽略这些冲突,因此将 main 合并到此分支,忽略 main 上的任何内容:
git merge -s ours main。 - 推送并打开一个 PR;squash 并合并。获取提交 SHA。
- 将提交 SHA 作为 ref 粘贴到
primer.py。 - 运行
sqlfmt_primer -k以清除缓存,然后更新primer.py中的统计信息以匹配结果。