如何使用sqlparse提取SQL WHERE子句并转换为条件JSON格式
实现方案
推荐优先使用sqlglot库完成需求,它是专门为SQL语法解析、AST操作设计的Python库,对各类SQL方言、运算符、嵌套条件的支持远好于sqlparse,不需要手动处理运算符优先级、括号嵌套等边界问题。
第一步:安装依赖
pip install sqlglot
第二步:核心实现代码
首先定义运算符映射规则,再通过递归遍历AST节点生成目标JSON结构:
import json import sqlglot from sqlglot import exp # 运算符映射:SQL运算符 -> 目标JSON的key OPERATOR_MAP = { "EQ": "eq", "NEQ": "ne", "GT": "gt", "LT": "lt", "GTE": "gte", "LTE": "lte", "AND": "and", "OR": "or", "NOT": "not", "IN": "in", "LIKE": "like", "REGEXP": "regexp" } def parse_expression(expr): # 处理逻辑运算(AND/OR) if isinstance(expr, exp.And) or isinstance(expr, exp.Or): op_key = OPERATOR_MAP[expr.key] return { op_key: [ parse_expression(expr.left), parse_expression(expr.right) ] } # 处理NOT运算 if isinstance(expr, exp.Not): return { "not": parse_expression(expr.this) } # 处理二元比较运算 if isinstance(expr, exp.Binary): op_key = OPERATOR_MAP.get(expr.key) if not op_key: raise ValueError(f"不支持的运算符: {expr.key}") # 左节点通常是字段名 col = expr.left.sql() # 右节点处理值,剥离引号、转换类型 value = expr.right.this if isinstance(expr.right, exp.Literal) else expr.right.sql() if isinstance(expr.right, exp.Literal): if expr.right.is_string: value = expr.right.this elif expr.right.is_number: value = float(expr.right.this) if "." in expr.right.this else int(expr.right.this) # 处理IN运算的多值情况 if op_key == "in": value = [ float(v.this) if v.is_number else v.this if v.is_string else v.sql() for v in expr.right.expressions ] return { op_key: {col: value} } raise ValueError(f"不支持的表达式类型: {type(expr)}") def sql_where_to_json(sql): # 解析SQL生成AST parsed = sqlglot.parse_one(sql) # 提取WHERE子句 where_expr = parsed.where if not where_expr: return {} # 递归解析生成结构 parsed_struct = parse_expression(where_expr) return json.dumps(parsed_struct, indent=2, ensure_ascii=False)
测试示例
输入你提供的测试SQL:
test_sql = "select * from Table where Col1= 'aaa' AND Col2 > 10" result = sql_where_to_json(test_sql) print(result)
输出结果(修正了你示例中JSON集合的笔误,JSON规范不支持集合类型,改用键值对对象):
{ "and": [ {"eq": {"Col1": "aaa"}}, {"gt": {"Col2": 10}} ] }
支持的场景
- 基础比较运算符:
=、<>、>、<、>=、<= - 逻辑运算符:
AND、OR、NOT,支持多层嵌套、括号优先级 - 集合/匹配运算符:
IN、LIKE、正则匹配运算符 - 自动处理值类型:字符串、整数、浮点数、IN子句的数组值
可选:sqlparse实现思路
如果必须使用sqlparse实现,核心思路如下:
- 遍历
sqlparse.parse返回的token树,提取WHERE关键字之后的所有token - 递归处理token分组:优先拆分括号内的子表达式,再拆分逻辑运算符AND/OR,最后拆分比较运算符
- 手动处理字符串引号识别、数值类型转换、运算符优先级排序
该方案需要手动处理大量边界情况,实现成本较高,仅在不能引入sqlglot依赖时考虑。
内容的提问来源于stack exchange,提问作者Nicola
相关产品推荐
相关产品推荐

