SQLFluff, i.e. keeping SQL queries clean

Surprisingly it may sound, keeping code formatted correctly is not only the matter of Python. If you are more of a SQL user, you can also implement additional linting controls with a library called SQLFluff.

4-day workshop · In-person or online

What would it take for you to trust your Databricks pipelines in production?

A 3-day bug hunt on a 3-person team costs up to €7,200 in lost engineering time. This workshop teaches you to prevent that — unit tests, data tests, and integration tests for PySpark and Databricks Lakeflow, including Spark Declarative Pipelines.

Unit, data & integration tests
Medallion architecture & Lakeflow SDP
Max 10 participants · production-ready templates
See the full curriculum → €7,000 flat fee · cohort of up to 10
Bartosz Konieczny
Bartosz
Konieczny
Surprisingly it may sound, keeping code formatted correctly is not only the matter of Python. If you are more of a SQL user, you can also implement additional linting controls with a library called SQLFluff.

SQLFluff 101

In a nutshell, SQLFluff is a linter for SQL designed for ELT workflows. Its main features include:

Configuration

SQLFluff has many configuration entries but the documentation recommends keeping things simple, which is a great recommendation for bootstrapping the projects. Consequently, the properties to look at are:

Don't be misled by the name. The Python templater is not a Python parser and it won't let you lint SQL queries declared in Python files. It only substitutes variables defined inside brackets (e.g. {table_name}) with context values. Consequently, if you want to lint SQL queries defined inside your Python code, you will have to extend SQLFluff with a dedicated parser, or use SQLFluff's Python API to lint the queries:

config = FluffConfig(overrides={"dialect": "databricks"})

linter_result = Linter(config=config).lint_string(get_active_users_query(table_name=table_for_linting))

The problem with those approaches will be lines' positions. Since both solutions extract SQL queries from Python code, they ignore all the lines before that are not part of the queries themselves.

A minimal configuration file for Apache Spark SQL/Databricks could then look like that:

[sqlfluff]
dialect = None
templater = raw
max_line_length = 80
exclude_rules = LT08, RF02

SQLFluff and Declarative Automation Bundles

Due to the file formats limitation - after all you won't be able to easily validate SQL queries written in your Python project - SQLFluff easily integrates with SQL or dbt projects on Lakeflow Jobs. Here is how you can define a Poe task to validate the SQL queries either as a pre-commit hook, or/and as part of your CI/CD process:

[tool.poe.tasks.validate_code]
help ="Lints and checks for formatting issues."
shell = """
sqlfluff lint queries/
"""

If you run it against the queries present in the Github repo for this blog post, you should see a few linting errors:

If so far you have been thinking that linting SQL queries is just a dream, SQLFluff shows it's not.

Data Engineering Design Patterns

Looking for a book that defines and solves most common data engineering problems? I wrote one on that topic! You can read it online on the O'Reilly platform, or get a print copy on Amazon.

I also help solve your data engineering problems contact@waitingforcode.com đź“©