{"id":13703226,"url":"https://github.com/tconbeer/sqlfmt","last_synced_at":"2025-10-09T08:59:16.299Z","repository":{"id":37951398,"uuid":"387531661","full_name":"tconbeer/sqlfmt","owner":"tconbeer","description":"sqlfmt formats your dbt SQL files so you don't have to","archived":false,"fork":false,"pushed_at":"2025-08-09T16:08:19.000Z","size":1604,"stargazers_count":485,"open_issues_count":54,"forks_count":24,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-29T14:23:12.943Z","etag":null,"topics":["dbt","formatter","python","sql"],"latest_commit_sha":null,"homepage":"https://sqlfmt.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tconbeer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["tconbeer"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2021-07-19T16:40:37.000Z","updated_at":"2025-09-25T15:12:03.000Z","dependencies_parsed_at":"2023-10-16T12:25:20.302Z","dependency_job_id":"c3d34d2f-a63c-4c23-b451-3ed3472f6a50","html_url":"https://github.com/tconbeer/sqlfmt","commit_stats":{"total_commits":272,"total_committers":10,"mean_commits":27.2,"dds":0.4411764705882353,"last_synced_commit":"decdd14d344bd66184f87c134f973998ccbbc734"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"purl":"pkg:github/tconbeer/sqlfmt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tconbeer%2Fsqlfmt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tconbeer%2Fsqlfmt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tconbeer%2Fsqlfmt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tconbeer%2Fsqlfmt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tconbeer","download_url":"https://codeload.github.com/tconbeer/sqlfmt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tconbeer%2Fsqlfmt/sbom","scorecard":{"id":870744,"data":{"date":"2025-08-11","repo":{"name":"github.com/tconbeer/sqlfmt","commit":"0e8e650fe4d13364c3183e9b783bd0baf401f83e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.6,"checks":[{"name":"Maintained","score":10,"reason":"8 commit(s) and 4 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":1,"reason":"Found 3/17 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/publish.yml:20","Warn: jobLevel 'deployments' permission set to 'write': .github/workflows/publish.yml:21","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/release.yml:14","Warn: no topLevel permission defined: .github/workflows/primer.yml:1","Warn: no topLevel permission defined: .github/workflows/publish.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/static.yml:1","Warn: no topLevel permission defined: .github/workflows/test-coverage.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/primer.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/primer.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/primer.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/primer.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/primer.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/primer.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/primer.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/primer.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/primer.yml:55: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/primer.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:64: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:79: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:82: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:89: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/publish.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/static.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/static.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/static.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/static.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/static.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/static.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/static.yml:44: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/static.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/static.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/static.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-coverage.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test-coverage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-coverage.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test-coverage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-coverage.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test-coverage.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test-coverage.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test-coverage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-coverage.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test-coverage.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test-coverage.yml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test-coverage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:84: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:90: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:96: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:107: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:113: update your workflow using https://app.stepsecurity.io/secureworkflow/tconbeer/sqlfmt/test.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating python:3-slim to python:3-slim@sha256:4d55aff3915a8622fdb8e6ab3645992de771bd97c3dd1279860cd5e18bcd7582","Warn: pipCommand not pinned by hash: Dockerfile:4","Info:   0 out of  25 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  17 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.27.0 not signed: https://api.github.com/repos/tconbeer/sqlfmt/releases/235726675","Warn: release artifact v0.26.0 not signed: https://api.github.com/repos/tconbeer/sqlfmt/releases/197039008","Warn: release artifact v0.25.0 not signed: https://api.github.com/repos/tconbeer/sqlfmt/releases/196734303","Warn: release artifact v0.24.0 not signed: https://api.github.com/repos/tconbeer/sqlfmt/releases/187066783","Warn: release artifact v0.23.3 not signed: https://api.github.com/repos/tconbeer/sqlfmt/releases/184963931","Warn: release artifact v0.27.0 does not have provenance: https://api.github.com/repos/tconbeer/sqlfmt/releases/235726675","Warn: release artifact v0.26.0 does not have provenance: https://api.github.com/repos/tconbeer/sqlfmt/releases/197039008","Warn: release artifact v0.25.0 does not have provenance: https://api.github.com/repos/tconbeer/sqlfmt/releases/196734303","Warn: release artifact v0.24.0 does not have provenance: https://api.github.com/repos/tconbeer/sqlfmt/releases/187066783","Warn: release artifact v0.23.3 does not have provenance: https://api.github.com/repos/tconbeer/sqlfmt/releases/184963931"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish.yml:11"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-cpwx-vrp4-4pq7","Warn: Project is vulnerable to: GHSA-7cx3-6m66-7c5m"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-24T04:08:12.153Z","repository_id":37951398,"created_at":"2025-08-24T04:08:12.153Z","updated_at":"2025-08-24T04:08:12.153Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001046,"owners_count":26082993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dbt","formatter","python","sql"],"created_at":"2024-08-02T21:00:52.167Z","updated_at":"2025-10-09T08:59:16.293Z","avatar_url":"https://github.com/tconbeer.png","language":"Python","funding_links":["https://github.com/sponsors/tconbeer"],"categories":["Utilities","SQL Linters \u0026 Formatters"],"sub_categories":["Rust"],"readme":"# sqlfmt\n\n[![PyPI](https://img.shields.io/pypi/v/shandy-sqlfmt)](https://pypi.org/project/shandy-sqlfmt/)\n[![Downloads](https://static.pepy.tech/personalized-badge/shandy-sqlfmt?period=month\u0026units=international_system\u0026left_color=grey\u0026right_color=orange\u0026left_text=downloads/mo)](https://pepy.tech/project/shandy-sqlfmt)\n[![Test](https://github.com/tconbeer/sqlfmt/actions/workflows/test.yml/badge.svg?branch=main\u0026event=push)](https://github.com/tconbeer/sqlfmt/actions/workflows/test.yml)\n\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/shandy-sqlfmt)\n![Runs on Linux | MacOS | Windows](https://img.shields.io/badge/runs%20on-Linux%20%7C%20MacOS%20%7C%20Windows-blue)\n\n\nsqlfmt formats your dbt SQL files so you don't have to. It is similar in nature to black, gofmt, \nand rustfmt (but for SQL). \n\n1. **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.\n2. **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.\n3. **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.\n3. **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.\n\nsqlfmt 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.\n\nsqlfmt 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.\n\nFor 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](https://github.com/tconbeer/sqlfmt/issues/262) for more information.\n\n## Documentation\n\nPlease visit [docs.sqlfmt.com](https://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.\n\n### Installation\n\n#### Try it first\nWant to test out sqlfmt on a query before you install it? Go to [sqlfmt.com](https://sqlfmt.com) to use the interactive, web-based version.\n\n#### Install Using pipx (recommended)\nsqlfmt is a pip-installable Python package listed on PyPI under the name `shandy-sqlfmt`. You should install it into a virtual environment, which `pipx` does automatically:\n\n```\npipx install shandy-sqlfmt\n```\n\nTo install with the jinjafmt extra (which will also install the Python code formatter, *black*):\n\n```\npipx install shandy-sqlfmt[jinjafmt]\n```\n\nFor more installation options, [read the docs](https://docs.sqlfmt.com/getting-started/installation).\n\n### Getting Started\n\n#### Other prerequisites\n**sqlfmt will not always produce the formatted output you might 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.\n\nThere are certain situations where sqlfmt can be considered to be in Beta, or even more mature than that. Those are:\n\n1. Using sqlfmt to format select statements for one of the major dialects (PostgresSQL, MySQL, Snowflake, BQ, Redshift).\n\n1. Using sqlfmt to format a dbt project (which may also include jinja and some minimal DDL/DML, like grants, create function, etc.) for one of the major dialects.\n\nHowever, there are other use cases where sqlfmt is very much alpha:\n\n1. Formatting some dialects that deviate from ANSI or Postgres, like T-SQL (SQLServer).\n\n1. Formatting other DDL (create table, insert, etc.) (sqlfmt attempts to be no-op on these statements as much as possible).\n\nIn these domains sqlfmt is nowhere near \"feature complete\" and caution is highly advised.\n\n#### Using sqlfmt\nTo list commands and options:\n\n```bash\nsqlfmt --help\n```\n\nIf you want to format all `.sql` and `.sql.jinja` files in your current working directory (and all nested directories), simply type:\n```bash\n$ sqlfmt .\n```\n\nIf you don't want to format the files you have on disk, you can run sqlfmt with the `--check` option. sqlfmt will exit with code 1 if the files on disk are not properly formatted:\n```bash\n$ sqlfmt --check .\n```\nIf you want to print a diff of changes that sqlfmt would make to format a file (but not update the file on disk), you can use the `--diff` option. `--diff` also exits with 1 on changes:\n```bash\n$ sqlfmt --diff .\n```\n\nFor more commands, see [the docs](https://docs.sqlfmt.com/getting-started/using-sqlfmt).\n\n#### Configuring sqlfmt using pyproject.toml\n\nAny 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](https://docs.sqlfmt.com/getting-started/configuring-sqlfmt) for more information.\n\n#### The jinjafmt extra\n\nsqlfmt loves properly-formatted jinja, too.\n\n[See the docs](https://docs.sqlfmt.com/getting-started/formatting-jinja) for more information about using the `jinjafmt` extra or disabling jinja formatting.\n\n### Using sqlfmt with different SQL dialects\n\nsqlfmt'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.\n\nThe exception to this is [ClickHouse](https://docs.sqlfmt.com/dialects/#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,\n\n```bash\n$ sqlfmt . --dialect clickhouse\n```\n\nThis can also be configured using the `pyproject.toml` file:\n\n```toml\n[tool.sqlfmt]\ndialect = \"clickhouse\"\n```\n\nNote 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](https://github.com/tconbeer/sqlfmt/discussions/229) for more on this topic.\n\n### Integrations\n\nsqlfmt plays nicely with other analytics engineering tools. For more information, [see the docs](https://docs.sqlfmt.com/category/integrations).\n\n#### dbt\n\nsqlfmt was built for dbt, so only [minimal configuration](https://docs.sqlfmt.com/integrations/dbt) 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:\n\n```toml\n[tool.sqlfmt]\nexclude=[\"target/**/*\", \"dbt_packages/**/*\"]\n```\n\n#### Other Integrations\n\nConfig for other integrations is detailed in the docs linked below:\n\n- [pre-commit](https://docs.sqlfmt.com/integrations/pre-commit)\n- [SQLFluff](https://docs.sqlfmt.com/integrations/sqlfluff)\n- [VSCode](https://docs.sqlfmt.com/integrations/vs-code)\n\n\n## The sqlfmt style\nThe 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.\n\nsqlfmt 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`).\n\nThe 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.\n\n[Read More](https://docs.sqlfmt.com/style/)\n\n### Why lowercase?\nBecause SQL is code! But there are [other good reasons too](https://docs.sqlfmt.com/style/#why-lowercase).\n\n### Why trailing commas?\nUsing trailing commas follows the convention of every other written language and programming language. [But wait, there's more.](https://docs.sqlfmt.com/style/#why-trailing-commas)\n\n## Contributing\n\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)\n[![Maintainability](https://api.codeclimate.com/v1/badges/8928f6662a67b8eaf092/maintainability)](https://codeclimate.com/github/tconbeer/sqlfmt/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/8928f6662a67b8eaf092/test_coverage)](https://codeclimate.com/github/tconbeer/sqlfmt/test_coverage)\n\n### Providing Feedback\n\nWe'd love to hear from you! [Open an Issue](https://github.com/tconbeer/sqlfmt/issues/new/choose) to request new features, report bad formatting, or say hello.\n\n### Setting up Your Dev Environment and Running Tests\n\n1. Install [Poetry](https://python-poetry.org/docs/#installation) v1.2 or higher if you don't have it already. You may also need or want pyenv, make, and gcc. A complete setup from a fresh install of Ubuntu can be found [here](https://github.com/tconbeer/linux_setup).\n1. Clone this repo into a directory (let's call it `sqlfmt`), then `cd sqlfmt`.\n1. Use `poetry install --all-extras --sync` to install the project (editable) and its dependencies (including the `jinjafmt` and `sqlfmt_primer` extras) into a new virtual env.\n1. Use `poetry shell` to spawn a subshell (if you are using Poetry v2.0 or higher, it is recommended that you use the command `eval $(poetry env activate)` instead. Alternatively, you can install the plugin [poetry-plugin-shell](https://github.com/python-poetry/poetry-plugin-shell)).\n2. Type `make` to run all tests and linters, or run `pytest`, `ruff`, and `mypy` individually.\n\n### Updating primer repos to reflect formatting changes\n\n1. Make sure all changes are committed to sqlfmt.\n1. Check out `main` in the repo and make sure you `pull` changes locally.\n1. 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).\n1. Run sqlfmt against the working tree, then `git add .` and `git commit -m \"chore: apply sqlfmt abc123\"`.\n1. 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`.\n1. Push and open a PR; squash and merge. Grab the commit SHA.\n1. Paste the commit SHA as a ref into `primer.py`.\n1. Run `sqlfmt_primer -k` to clear the cache, then update the stats in `primer.py` to match the results.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftconbeer%2Fsqlfmt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftconbeer%2Fsqlfmt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftconbeer%2Fsqlfmt/lists"}