当前位置: 首页 > news >正文

【Python 小工具】一键把源表 INSERT SQL 转换成目标表 INSERT SQL

背景

在微服务/多租户系统里,经常会出现两张结构相近但用途不同的表:

  • SRC_T(运行期完整数据,含租户字段 TENANT_COL
  • DST_T(初始化模板表,无租户字段,字段顺序也不同)

当运营同事在测试环境通过 UI 配置完一整套数据后,需要把生成的 SRC_T INSERT 语句“迁移”到 DST_T,供初始化脚本复用。
手动改字段非常痛苦,于是写了一个小脚本,一条命令搞定。


两张表的区别

字段SRC_TDST_T
TENANT_COL
STATUS_COL
FLAG_A1/2统一 2
FLAG_B0/1统一 1
FLAG_C0/1统一 0
字段顺序24 列22 列

脚本功能

  • 读取任意 .sql 文件,自动提取所有 INSERT INTO … SRC_T … 语句。
  • 自动补齐缺失字段,并重排顺序。
  • CODE_COL 为空时,用 ID_COL 的 MD5 生成 32 位唯一值。
  • 生成可直接执行的 dst.sql

源码(单文件,零依赖)

复制即可运行,Python 3.7+

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
convert_generic.py
把 SRC_T 的 INSERT SQL 转成 DST_T 的 INSERT SQL
"""import re
import hashlib
from pathlib import Path# 目标表字段顺序(按业务需要调整)
TARGET_COLS = ['COL_01', 'COL_02', 'COL_03', 'COL_04', 'COL_05', 'COL_06', 'COL_07','COL_08', 'COL_09', 'COL_10', 'COL_11', 'COL_12', 'COL_13', 'COL_14','COL_15', 'COL_16', 'COL_17', 'COL_18', 'COL_19', 'COL_20', 'COL_21','COL_22'
]# 统一写死的默认值
DEFAULTS = {'COL_15': 2, 'COL_16': 1, 'COL_17': 0}def md5_32(s: str) -> str:return hashlib.md5(s.encode()).hexdigest()def parse_insert(line: str) -> dict:line = line.strip().rstrip(';')m = re.search(r'VALUES\s*\((.+)\)', line, re.S | re.I)if not m:return Nonevalues = [v.strip().strip("'\"") or Nonefor v in re.split(r''',(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', m.group(1))]# 源表字段顺序(按实际调整)SRC_COLS = ['COL_01', 'COL_02', 'COL_03', 'COL_04', 'COL_05', 'COL_06', 'COL_07','COL_08', 'COL_09', 'COL_10', 'COL_11', 'COL_12', 'COL_13', 'COL_14','STATUS_COL', 'FLAG_C', 'FLAG_A', 'COL_18', 'COL_19', 'COL_20','COL_21', 'COL_22', 'COL_23', 'COL_24', 'TENANT_COL', 'FLAG_B']record = dict(zip(SRC_COLS, values))# 类型转换示例for k in ['COL_01', 'COL_04', 'COL_05', 'COL_18', 'COL_20']:if str(record.get(k, '')).lstrip('-').isdigit():record[k] = int(record[k])record['COL_11'] = str(record.get('COL_11', '0'))# 空 CODE 自动生成if not record.get('COL_02'):record['COL_02'] = md5_32(str(record['COL_01']))return recorddef convert(src_file: Path, dst_file: Path):text = src_file.read_text(encoding='utf-8')inserts = re.findall(r'INSERT\s+INTO\s+(?:`?\w+`?\.)?`?SRC_T`?\s*\([^)]*\)\s*VALUES\s*\([^)]*\);',text, re.I | re.S)records = [parse_insert(i) for i in inserts if parse_insert(i)]sql_lines = []for rec in records:for k, v in DEFAULTS.items():rec.setdefault(k, v)values = []for col in TARGET_COLS:val = rec.get(col)if val is None or str(val).upper() == 'NULL':values.append('NULL')elif isinstance(val, int):values.append(str(val))else:values.append(f"'{str(val).replace(\"'\", \"''\")}'")cols_sql = ', '.join(f'`{c}`' for c in TARGET_COLS)vals_sql = ', '.join(values)sql_lines.append(f"INSERT INTO DST_T ({cols_sql}) VALUES ({vals_sql});")dst_file.write_text('\n'.join(sql_lines), encoding='utf-8')print(f'✅ 已生成 {dst_file},共 {len(sql_lines)} 条记录。')if __name__ == '__main__':import syssrc_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path('input.sql')dst_path = src_path.with_name('dst.sql')convert(src_path, dst_path)

使用方法

  1. 把脚本保存为 convert_generic.py
  2. 把需要转换的 SQL 文件(例如 input.sql)放到相同目录。
  3. 打开终端:
python convert_generic.py input.sql
  1. 目录下会生成 dst.sql,直接导入即可:
mysql -h127.0.0.1 -uroot -p target_db < dst.sql

效果示例

输入(SRC_T 片段)

INSERT INTO `db_placeholder`.`SRC_T`
(`COL_01`, `COL_02`, `COL_03`, `COL_04`, `COL_05`, `COL_06`, ...)
VALUES
(1234567890123456000, 'abc123', '示例菜单', 0, 1, 'path_demo', ...);

输出(DST_T)

INSERT INTO DST_T
(`COL_01`, `COL_02`, `COL_03`, `COL_04`, `COL_05`, `COL_06`, ...)
VALUES
(1234567890123456000,'abc123','示例菜单',0,1,'path_demo',...);

小结

  • 纯正则解析,不依赖数据库客户端。
  • 支持任意库名前缀(db.SRC_T)。
  • 一键生成,再也不用手工改字段啦!

如需扩展(增删列、过滤条件等),直接改 TARGET_COLSSRC_COLSDEFAULTS 字典即可。

http://www.lryc.cn/news/624800.html

相关文章:

  • 华为认证 HCIA/HCIP/HCIE 全面解析(2025 版)
  • Next.js 性能优化:打造更快的应用
  • docker——docker执行roslaunch显示错误
  • Harmonyos之字体设置功能
  • Java任务执行队列的优化
  • 王树森深度强化学习DRL(三)围棋AlphaGo+蒙特卡洛
  • 《Python学习之第三方库:开启无限可能》
  • 【网络安全实验报告】实验六: 病毒防护实验
  • 【加密PMF】psk-pmk-ptk
  • 使用WinDbg对软件崩溃信息进行抓包的方法
  • AI 在金融领域的落地案例
  • 为Vue TypeScript 项目添加 router 路由,跳转到Chat AI页面
  • 2025 年无毒冷却液市场深度全景调研及投资前景分析
  • Qwen Code宣布每天免费调用2000次,且无Token限制
  • 物联网智能边缘架构:流数据处理与设备管理的协同优化
  • Linux常用命令详解
  • 增强服务器防御能力的自动化工具 Fail2Ban
  • MySQL实战优化高手教程 – 从架构原理到生产调优
  • iOS 正式包签名指南
  • 【C#补全计划】预处理器指令
  • 【MongoDB】常见八股合集,mongodb的特性,索引使用,优化,事务,ACID,聚合查询,数据复制机制,理解其基于raft的选举机制
  • 【Langchain系列五】DbGPT——Langchain+PG构建结构化数据库智能问答系统
  • MongoDB新手教学
  • Flutter 多功能列表项:图标、文字与Switch组合
  • 在阿里云 CentOS Stream 9 64位 UEFI 版上离线安装 Docker Compose
  • 智能人形机器人:知识驱动的工业生产力革新
  • 神经网络显存占用分析:从原理到优化的实战指南
  • 实战架构思考及实战问题:Docker+‌Jenkins 自动化部署
  • 【论文阅读】-《GeoDA: a geometric framework for black-box adversarial attacks》
  • 动态规划:入门思考篇