如何将pglast包生成的AST以图形化形式展示?
如何图形化展示pglast生成的PostgreSQL AST?
你已经通过pglast生成了SQL的AST:
from pglast import parse_sql parsed_sql = parse_sql("SELECT age FROM (select * from users group by age) as age_table WHERE age > 18;") print(parsed_sql)
执行后输出的AST结构如下:
(<RawStmt stmt=<SelectStmt targetList=(<ResTarget val=<ColumnRef fields=(<String sval='age'>,)>>,) fromClause=(<RangeSubselect lateral=False subquery=<SelectStmt targetList=(<ResTarget val=<ColumnRef fields=(<A_Star>,)>>,) fromClause=(<RangeVar relname='users' inh=True relpersistence='p'>,) groupClause=(<ColumnRef fields=(<String sval='age'>,)>,) groupDistinct=False limitOption=<LimitOption.LIMIT_OPTION_DEFAULT: 0> op=<SetOperation.SETOP_NONE: 0> all=False> alias=<Alias aliasname='age_table'>>,) whereClause=<A_Expr kind=<A_Expr_Kind.AEXPR_OP: 0> name=(<String sval='>'>,) lexpr=<ColumnRef fields=(<String sval='age'>,)> rexpr=<A_Const isnull=False val=<Integer ival=18>>> groupDistinct=False limitOption=<LimitOption.LIMIT_OPTION_DEFAULT: 0> op=<SetOperation.SETOP_NONE: 0> all=False> stmt_location=0 stmt_len=78>,)
实现图形化展示的方法
pglast本身没有内置的图形化AST展示函数,但可以通过以下两种方式实现:
1. 用Graphviz生成可视化图形
通过pglast的ast_to_dot函数将AST转换为DOT格式,再用Graphviz渲染成图片:
from pglast import parse_sql, ast_to_dot from graphviz import Source # 解析SQL并获取核心SelectStmt节点 parsed_sql = parse_sql("SELECT age FROM (select * from users group by age) as age_table WHERE age > 18;") stmt_node = parsed_sql[0].stmt # 生成DOT代码 dot_code = ast_to_dot(stmt_node) # 渲染并展示图形 graph = Source(dot_code) graph.render("sql_ast", format="png") # 保存为png文件 graph.view() # 打开预览窗口
- 依赖:需要安装
graphvizPython库(pip install graphviz),同时系统需安装Graphviz工具(如Ubuntu用apt install graphviz,Windows需下载官方安装包并配置环境变量)。
2. 生成文本树形结构(快速查看层级)
如果不需要图形化图片,可使用treelib库生成文本格式的树形AST:
from pglast import parse_sql from treelib import Tree def traverse_ast(tree, node, parent_id=None): # 生成节点ID和标签 node_id = id(node) node_label = type(node).__name__ # 补充节点的关键属性值 if hasattr(node, 'sval'): node_label += f": {node.sval}" elif hasattr(node, 'ival'): node_label += f": {node.ival}" elif hasattr(node, 'relname'): node_label += f": {node.relname}" elif hasattr(node, 'aliasname'): node_label += f": {node.aliasname}" tree.create_node(node_label, node_id, parent=parent_id) # 递归遍历子节点 for attr, value in vars(node).items(): if isinstance(value, (list, tuple)): for item in value: if hasattr(item, '__dict__'): traverse_ast(tree, item, node_id) elif hasattr(value, '__dict__'): traverse_ast(tree, value, node_id) # 解析SQL并生成树形结构 parsed_sql = parse_sql("SELECT age FROM (select * from users group by age) as age_table WHERE age > 18;") ast_tree = Tree() traverse_ast(ast_tree, parsed_sql[0].stmt) # 打印树形结构 ast_tree.show()
- 依赖:安装
treelib库(pip install treelib),这种方式适合快速查看AST的层级关系,无需额外系统工具。
内容的提问来源于stack exchange,提问作者Kushdesh
相关产品推荐
相关产品推荐

