如何在 Python 中高效删除 SQL 文件中所有含 “Key” 的约束语句

4次阅读

如何在 Python 中高效删除 SQL 文件中所有含 “Key” 的约束语句

本文介绍使用正则表达式精准移除 mariadb 导出 sql 中不兼容 sqlite 的 PRIMARY KEY、FOREIGN KEY 等约束子句,适用于处理大体积(如 3GB)SQL 文件,兼顾准确性与内存效率。

本文介绍使用正则表达式精准移除 mariadb 导出 sql 中不兼容 sqlite 的 `primary key`、`foreign key` 等约束子句,适用于处理大体积(如 3gb)sql 文件,兼顾准确性与内存效率。

在将 MariaDB 导出的大型 SQL 文件(例如 3GB)迁移到 SQLite 时,一个常见障碍是 SQLite 不支持 PRIMARY KEY(…) 或 FOREIGN KEY(…) 这类列级或表级约束语法(尤其是带括号参数的显式 Key 声明)。直接用字符串替换或简单正则易误删合法内容(如字段名含 key),因此需设计语义感知型正则模式,精准匹配以 Key( 开头、以 ) 结尾、且位于建表语句内的约束片段。

以下推荐方案采用 re.sub() 配合多分支正则,可安全清除各类 Key 约束并自动处理逗号分隔与换行空白:

import re  def remove_key_constraints(sql_content: str) -> str:     """     移除 SQL 字符串中所有形如 'PRIMARY KEY(...)'、'FOREIGN KEY(...)' 的约束子句,     同时自动清理前导逗号、多余空白及换行,保持 SQL 结构整洁。     """     # 匹配模式说明:     # - s*[,;]?s* :匹配前置可选逗号/分号及空白(用于删除后避免残留逗号)     # - b(?:PRIMARY|FOREIGN|UNIQUE)s+KEYs*([^)]*) :匹配关键词 + KEY + 括号内任意非右括号内容     # - s*(?:,|;|)|n|$) :匹配约束后紧跟的分隔符(逗号、分号、右括号、换行或行尾)     pattern = r's*[,;]?s*b(?:PRIMARY|FOREIGN|UNIQUE)s+KEYs*([^)]*)s*(?:,|;|)|n|$)'      # 替换为空字符串,并多次迭代确保嵌套/连续约束被清除(re.sub 默认全局)     cleaned = re.sub(pattern, '', sql_content, flags=re.IGNORECASE | re.MULTILINE)      # 可选:进一步压缩连续空白(提升可读性,非必需)     cleaned = re.sub(r',s*)', ')', cleaned)  # 清理形如 ',)' 的残留     cleaned = re.sub(r'ns*n', 'nn', cleaned)  # 合并空行      return cleaned  # 示例使用 input_sql = """CREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255), Primary Key(`PersonID`), Foreign Key(`City`) );"""  output_sql = remove_key_constraints(input_sql) print(output_sql)

输出效果:

CREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) );

关键优势与注意事项:

立即学习Python免费学习笔记(深入)”;

  • 精准匹配:b 确保 Key 是独立单词(避免误删 apikey 或 keyword);[^)]* 限定括号内无嵌套,防止跨行误匹配;
  • 大小写不敏感:re.IGNORECASE 兼容 PRIMARY KEY / primary key 等变体;
  • 大文件友好:对 3GB 文件,建议流式处理而非一次性读入内存——可用 mmap 或逐行/块读取(注意约束可能跨行,需缓冲上下文);
  • 安全兜底:操作前务必备份原始文件;对生产数据,先用小样本验证正则逻辑;
  • 扩展性:如需同时移除 INDEX、ENGINE= 等 mysql 特有语法,可扩展正则或叠加 re.sub() 调用。

⚠️ 提示:若 SQL 文件中存在注释(如 — PRIMARY KEY(id))或字符串字面量(如 ‘some key value’),上述正则可能误匹配。此时需改用 SQL 解析器(如 sqlparse)进行语法树分析,但会显著增加复杂度与开销。对于纯迁移场景,本正则方案在准确率与性能间取得了最佳平衡。

text=ZqhQzanResources