基于Bazel + SQLFluff实现SQL lint

背景 SQL进行版本化控制后,我们希望为SQL加入lint步骤。这样做的好处是我们可以在真正执行SQL前发现问题。 本文中,我们通过Bazel执行SQLFluff以实现SQL的lint。 SQLFluff是一款使用Python语言使用的,支持SQL多方言的SQL lint工具。 它的特点是: 支持多方言。如:Snowflake、PostgreSQL、ClickHouse。所有支持的方言列表:https://docs.sqlfluff.com/en/stable/dialects.html; 可以输出正确的SQL,减少了我们手工修正SQL的工作; 同时支持命令行方式使用和API调用方式。 集成到CI/CD流水线中 在我看来,在CICD流水线中实现SQL lint有两种方式: 方式一:在流水线中增加一个SQL lint步骤; 方式二:将SQL lint的逻辑写在测试代码,执行测试步骤,就自动执行了SQL lint。 方式二是我最爱,我会在本文最后讲原因。 工程结构 . ├── BUILD.bazel ├── WORKSPACE ├── repository-hibernate-impl │ ├── BUILD.bazel │ └── src │ ├── main │ │ └── sql │ │ └── V1__runbook_table.sql │ └── test │ └── python │ ├── BUILD.bazel │ ├── requirements_lock.txt │ └── sql_test.py 步骤1: 在WORKSPACE中增加Python外部依赖 本文中我们使用的是Bazel 5.4.0,所以还在使用WORKSPACE定义外部依赖 http_archive( name = "rules_python", sha256 = "a644da969b6824cc87f8fe7b18101a8a6c57da5db39caa6566ec6109f37d2141", strip_prefix = "rules_python-0.20.0", url = "https://github.com/bazelbuild/rules_python/releases/download/0.20.0/rules_python-0.20.0.tar.gz", ) load("@rules_python//python:repositories.bzl", "py_repositories") py_repositories() load("@rules_python//python:repositories.bzl", "python_register_toolchains") python_register_toolchains( name = "python3_11", python_version = "3.11", ) load("@python3_11//:defs.bzl", interpreter_3_11 = "interpreter") load("@rules_python//python:pip.bzl", "pip_parse") # Create a central repo that knows about the dependencies needed from # requirements_lock.txt. pip_parse( name = "pip_deps", python_interpreter_target = interpreter_3_11, requirements_lock = "//repository-hibernate-impl/src/test/python:requirements_lock.txt", ) # Load the starlark macro which will define your dependencies. load("@pip_deps//:requirements.bzl", "install_deps") # Call it to define repos for your requirements. install_deps() 步骤2: 定义SQLFluff依赖 requirements_lock.txt的内容如下: ...

2023-04-17 · 2 min · 315 words · 翟志军 Jack Zhai