You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否存在SQLFluff函数可将解析后的查询字典还原为SQL字符串?

如何将SQLFluff解析后的字典重构为SQL查询字符串

SQLFluff官方确实没有提供直接将.parse()返回的字典转回SQL的API,但可以通过以下两种方式实现需求:

方法1:利用SQLFluff内部AST序列化逻辑

SQLFluff的解析字典对应其内部的抽象语法树(AST)节点结构,我们可以通过构建对应的AST节点对象,调用其序列化方法生成SQL:

import sqlfluff
from sqlfluff.core.parser.segments import RawSegment, BaseSegment

def dict_to_sql(ast_dict, dialect="postgres"):
    dialect_obj = sqlfluff.get_dialect(dialect)
    
    def build_segment(node):
        if isinstance(node, list):
            return [build_segment(item) for item in node]
        if isinstance(node, dict):
            if len(node) == 1:
                seg_type, content = next(iter(node.items()))
                # 处理基础文本节点
                if seg_type in ["keyword", "whitespace", "comma", "dot", "star", "raw_comparison_operator", "start_bracket", "end_bracket"]:
                    return RawSegment(content, dialect=dialect_obj)
                # 匹配复合节点类
                for cls in BaseSegment.__subclasses__():
                    if cls.__name__.lower() == seg_type:
                        return cls(children=build_segment(content), dialect=dialect_obj)
                # 兜底处理未知节点
                return BaseSegment(children=build_segment(content), dialect=dialect_obj)
        return node
    
    root_segment = build_segment(ast_dict["file"]["statement"])
    return root_segment.serialized

# 测试示例
parsed_result = sqlfluff.parse(
    """with cte1 as (select colA from table1), cte2 as (select colB from table2 inner join table1 on table2.colB = table1.colA) select * from cte2""",
    "postgres"
)
print(dict_to_sql(parsed_result))

方法2:递归遍历字典拼接SQL

直接递归遍历解析字典的键值对,提取文本内容拼接成SQL,这种方式更轻量但需要覆盖所有可能的节点类型:

def reconstruct_sql(ast_node):
    sql_parts = []
    if isinstance(ast_node, list):
        for item in ast_node:
            sql_parts.append(reconstruct_sql(item))
    elif isinstance(ast_node, dict):
        for key, value in ast_node.items():
            # 提取直接存储文本的节点
            if key in ["keyword", "whitespace", "comma", "dot", "star", "raw_comparison_operator", "start_bracket", "end_bracket", "naked_identifier"]:
                sql_parts.append(str(value))
            else:
                sql_parts.append(reconstruct_sql(value))
    return "".join(sql_parts)

# 测试示例
parsed_result = sqlfluff.parse(
    """with cte1 as (select colA from table1), cte2 as (select colB from table2 inner join table1 on table2.colB = table1.colA) select * from cte2""",
    "postgres"
)
print(reconstruct_sql(parsed_result["file"]["statement"]))

注意事项

  • 复杂SQL(如子查询、窗口函数、注释、特殊语法)需要补充对应节点的处理逻辑,两种方法才能完整生成原始SQL。
  • 方法1依赖SQLFluff内部类结构,版本更新后可能需要适配;方法2更稳定,但需要手动维护节点类型与文本的映射关系。

内容的提问来源于stack exchange,提问作者Eric Mendes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:57:02