SQLFluff自定义规则Rule_LL99未加载,Lint无预期结果求助
SQLFluff自定义规则不生效问题排查
自定义规则代码
规则文件custom_rules.py与.sqlfluff同级,代码如下:
from sqlfluff.core.rules import BaseRule, LintResult from sqlfluff.core.parser import BaseSegment class Rule_LL99(BaseRule): """Ensure columns with functions are aliased""" def _eval(self, segment: BaseSegment, **kwargs): print(f"Evaluating segment: {segment}") if segment.is_type('function'): parent_segment = segment.parent if parent_segment and not any(child.is_type('alias_expression') for child in parent_segment.segments): return LintResult(anchor=segment, description="Columns where Function has been used must be aliased") return None
测试SQL
SELECT id, status, LOWER("text"), CAST("test" AS STRING) FROM test
规则加载配置
在.sqlfluff中配置:
[sqlfluff:rules] custom_rules = custom_rules::Rule_LL99
运行Lint后的输出
=== [dbt templater] Sorting Nodes... === [dbt templater] Compiling dbt project... === [dbt templater] Project Compiled. All Finished 📜 🎉!
问题描述
单独写Python脚本测试时发现规则名称相关问题,但Lint过程中没有任何报错提示,排查困难。本人非Python开发者,求指出配置或代码中的明显问题。完整SQLFluff配置如下:
[sqlfluff] templater = dbt dialect = bigquery exclude_rules = RF02, AL01, AL05, ST07, AL03 [sqlfluff:templater:dbt] project_dir = ./ [sqlfluff:indentation] tab_space_size = 2 indented_joins = true indented_using_on = false [sqlfluff:rules] custom_rules = custom_rules::Rule_LL99 [sqlfluff:rules:capitalisation.keywords] capitalisation_policy = upper [sqlfluff:rules:capitalisation.identifiers] extended_capitalisation_policy = lower [sqlfluff:rules:capitalisation.functions] extended_capitalisation_policy = upper [sqlfluff:rules:capitalisation.literals] capitalisation_policy = upper [sqlfluff:rules:capitalisation.types] extended_capitalisation_policy = upper [sqlfluff:rules:aliasing.length] min_alias_length = 3
问题分析与修复方案
1. 规则命名不符合SQLFluff规范
SQLFluff对自定义规则的命名有强制要求:必须遵循Rule_{X}{XX}格式,其中X是单个字母(代表规则类别),后面跟三位数字。你的规则名Rule_LL99用了两个字母,不符合规范,导致SQLFluff无法正确识别加载规则,因此Lint过程中既不会触发规则,也不会输出加载失败的报错。
修复:将规则名改为符合规范的格式,比如Rule_L099,同时同步修改配置中的规则引用:
[sqlfluff:rules] custom_rules = custom_rules::Rule_L099
2. 规则逻辑存在错误
当前代码中,function的父节点是expression,而alias_expression属于select_target节点的子元素,所以通过parent_segment无法找到别名,导致规则逻辑失效。
修复:调整规则逻辑,直接遍历select_target节点,检查其中是否包含函数且未设置别名:
from sqlfluff.core.rules import BaseRule, LintResult from sqlfluff.core.parser import BaseSegment class Rule_L099(BaseRule): """Ensure columns with functions are aliased""" def _eval(self, segment: BaseSegment, **kwargs): # 只处理SELECT语句中的目标列节点 if segment.is_type('select_target'): # 检查当前列是否包含函数 has_function = any(child.is_type('function') for child in segment.recursive_crawl('function')) # 检查当前列是否有别名 has_alias = any(child.is_type('alias_expression') for child in segment.segments) if has_function and not has_alias: # 找到第一个函数节点作为报错锚点 func_segment = next(segment.recursive_crawl('function')) return LintResult(anchor=func_segment, description="使用函数的列必须指定别名") return None
3. 开启调试日志排查加载问题
默认SQLFluff日志级别较低,看不到规则加载失败的细节。运行Lint时加上--verbose参数,或者设置环境变量LOG_LEVEL=DEBUG,就能看到规则加载的详细日志,方便排查问题:
sqlfluff lint --verbose
内容的提问来源于stack exchange,提问作者Moseleyi
相关产品推荐
相关产品推荐

