Python脚本提取SQL文件中INSERT语句的列与值并结构化处理
Python脚本提取SQL文件中INSERT语句的列与值并结构化处理
嘿,这个问题我之前处理过好几次!直接用split(', ')确实会踩坑——毕竟像category字段里的Sport,Food,Creature或者描述文本里的逗号,都会把原本的字段值拆得乱七八糟。给你两个靠谱的解决思路,按需选就行:
方案一:用专业SQL解析库(最稳妥)
推荐用sqlparse这个专门的SQL解析库,它能精准识别SQL语法里的各种元素,哪怕字段值里有逗号也不会搞错拆分逻辑。
首先安装库:
pip install sqlparse
然后写脚本处理你的SQL文件:
import sqlparse from sqlparse.sql import IdentifierList, Identifier from sqlparse.tokens import Token def extract_insert_data(sql_file_path): # 读取目标SQL文件 with open(sql_file_path, 'r', encoding='utf-8') as f: sql_content = f.read() # 解析整个SQL内容 parsed_sql = sqlparse.parse(sql_content) # 用来存储最终结构化的数据(列表套字典) structured_data = [] for statement in parsed_sql: # 只处理INSERT类型的语句 if statement.get_type() != 'INSERT': continue columns = [] # 遍历语句里的每个token,提取列名和值 for token in statement.tokens: # 匹配列名列表的部分 if isinstance(token, IdentifierList): columns = [ident.value.strip('`') for ident in token.get_identifiers()] # 找到VALUES关键字,后面就是数据行 elif token.ttype is Token.Keyword and token.value.upper() == 'VALUES': values_section = token.next while values_section: if isinstance(values_section, IdentifierList): # 处理每一行数据 for row in values_section.get_identifiers(): row_values = [] for val_token in row.tokens: # 提取字符串、数字、布尔等类型的值,去掉多余的引号/反引号 if val_token.ttype in (Token.String, Token.Number, Token.Name): clean_val = val_token.value.strip("'\"`") row_values.append(clean_val) # 把列名和对应的值拼成字典,加入结果列表 if len(columns) == len(row_values): structured_data.append(dict(zip(columns, row_values))) values_section = values_section.next return structured_data # 调用示例,替换成你的SQL文件路径 if __name__ == '__main__': result = extract_insert_data('your_data.sql') for item in result: print(item)
这个脚本会自动帮你处理所有带逗号的字段值,完全不用担心拆分错误,而且能兼容绝大多数标准的INSERT语句。
方案二:用正则表达式(无额外依赖)
如果不想安装第三方库,也可以用正则表达式来匹配,核心思路是优先捕获带引号的内容,避免把字段值里的逗号当成分隔符。不过要注意,这个方案对复杂SQL(比如值里有转义引号)的兼容性不如专业库,但应付你给出的示例场景完全没问题。
脚本代码如下:
import re def extract_insert_data_with_regex(sql_file_path): with open(sql_file_path, 'r', encoding='utf-8') as f: sql_content = f.read() # 匹配INSERT语句的正则,捕获列名部分和值部分 insert_regex = re.compile(r'INSERT INTO `?\w+`? \((.*?)\) VALUES(.*?);', re.DOTALL) # 匹配单个值的正则:优先匹配带单引号/反引号的内容,再匹配不带引号的内容 value_regex = re.compile(r"'(.*?)'|`(.*?)`|([^,]+)") structured_data = [] for match in insert_regex.finditer(sql_content): columns_str = match.group(1) values_str = match.group(2) # 提取并清理列名 columns = [col.strip().strip('`') for col in columns_str.split(',')] # 拆分每一行数据(按括号分割) data_rows = re.findall(r'\((.*?)\)', values_str) for row in data_rows: row_values = [] # 匹配该行的每个值 for val_match in value_regex.finditer(row): # 优先取单引号里的内容,再取反引号,最后取不带引号的 val = val_match.group(1) or val_match.group(2) or val_match.group(3) if val is not None: clean_val = val.strip() # 处理NULL值 if clean_val.upper() == 'NULL': row_values.append(None) else: row_values.append(clean_val) # 拼接成字典加入结果 if len(columns) == len(row_values): structured_data.append(dict(zip(columns, row_values))) return structured_data # 调用示例 if __name__ == '__main__': result = extract_insert_data_with_regex('your_data.sql') for item in result: print(item)
运行这两个脚本后,你就能得到一个由字典组成的列表,每个字典对应一条INSERT语句里的行数据,键是列名,值是对应的字段内容。
备注:内容来源于stack exchange,提问作者curt




