SQLGlot解析带{{parameter}}的SQL抛错,是否支持Databricks式参数插值?
解决SQLGlot解析含
{{parameter}}格式参数的SQL报错问题 SQLGlot默认不支持{{...}}这种双大括号参数语法,不过可以通过以下两种方式处理,既能避免解析错误,又能保留原标记用于测试验证:
1. 自定义占位符规则
SQLGlot支持通过placeholder参数配置自定义占位符格式,直接匹配双大括号包裹的内容即可。示例代码:
from sqlglot import parse_one sql = """SELECT * FROM table WHERE parameter is {{parameter}}""" # 配置占位符正则匹配{{参数名}}格式 parsed = parse_one(sql, placeholder=r"\{\{(\w+)\}\}") # 输出解析后的SQL,会保留占位符结构 print(parsed.sql())
这个方法最简单,新版本的SQLGlot都支持自定义占位符正则,能直接让解析器识别{{parameter}}为合法元素,不会抛出ParseError。
2. 扩展解析器(进阶方案)
如果需要更定制化的处理(比如和Databricks的参数插值逻辑完全对齐),可以扩展SQLGlot的解析器,自定义词法分析规则来识别双大括号标记。示例思路:
from sqlglot import exp, parse_one from sqlglot.tokens import TokenType from sqlglot.lexer import Lexer # 自定义Lexer识别{{...}} class CustomLexer(Lexer): def next_token(self): token = super().next_token() if token and token.type == TokenType.LBRACE: # 检查下一个token是否也是LBRACE,即{{ next_token = super().next_token() if next_token and next_token.type == TokenType.LBRACE: # 读取直到}}的内容 buffer = [] while True: t = super().next_token() if t and t.type == TokenType.RBRACE: t2 = super().next_token() if t2 and t2.type == TokenType.RBRACE: break buffer.append(t.value) param_name = "".join(buffer) # 返回自定义的参数Token return self.token(TokenType.IDENTIFIER, f"{{{{{param_name}}}}}") return token # 使用自定义Lexer解析 parsed = parse_one(sql, lexer=CustomLexer)
这个方案适合需要深度定制参数处理逻辑的场景,不过仅用于验证SQL结构的话,第一种占位符配置足够满足需求。
版本说明
确保使用SQLGlot 11.0.0及以上版本,旧版本可能不支持placeholder参数的正则配置功能。
内容的提问来源于stack exchange,提问作者user16458812
相关产品推荐
相关产品推荐

