SQL Dump 转 JSON Mock:解析、脱敏、批量与类型边界
SQL dump 转成测试 JSON,目标是得到可复用的 fixture,而不是重建生产数据库。解析器必须先识别表、列和值,脱敏规则要在输出前执行,批量数据还要控制数量与类型损失。本文只讨论 dump 到 Mock 数据的处理链,不讨论真实数据库写入。
一、问题概述:dump 中的值不是普通逗号分隔文本
INSERT 语句会同时出现字符串逗号、转义引号、NULL、十进制数和多组 VALUES。直接按逗号或换行切分,可能把一条记录拆坏;把原文复制成 JSON,又会把 SQL 类型和敏感字段问题推迟到测试运行时。
二、最小复现:先得到已解析的行
下面的类型表示 parser 已经完成词法和方言处理。它不是某个库的未验证 API;实际项目应把目标方言 parser 适配为同样的 ParsedRow 结构。
type ParsedRow = {
table: string;
columns: string[];
values: unknown[];
};
const parsed: ParsedRow[] = [
{ table: "users", columns: ["id", "email", "active"], values: [7, "ada@example.test", true] },
{ table: "users", columns: ["id", "email", "active"], values: [8, null, false] },
];
console.log(parsed[0].values); // [7, "ada@example.test", true]三、根因:SQL parser 与 Mock 生成是两个阶段
parser 负责识别方言、引号、注释、批量 VALUES 和 SQL 字面量;Mock 生成器负责列名对齐、字段策略和输出格式。把两步混在一个正则里,无法区分解析失败、类型转换和脱敏失败,也很难定位哪一行被丢弃。
四、推荐方案:解析后按字段策略生成 fixture
先将每行转换成列名到值的对象,再应用字段级策略。未知表或列应报告为待确认,而不是静默删除。需要保留关联关系时,保留原始主键形状或用明确的映射表替换,避免 Mock 数据在测试中失去可追踪性。
五、完整代码:脱敏并生成批量 JSON
以下代码只处理已解析行,示例用固定规则遮蔽邮箱;它不声称能解析 SQL。批量大小通过参数控制,数组中的每个对象都保留列名和值的对应关系。
type ParsedRow = { table: string; columns: string[]; values: unknown[] };
const parsed: ParsedRow[] = [
{ table: "users", columns: ["id", "email", "active"], values: [7, "ada@example.test", true] },
{ table: "users", columns: ["id", "email", "active"], values: [8, null, false] },
];
type Redactor = (column: string, value: unknown) => unknown;
function redactEmail(column: string, value: unknown): unknown {
if (column === "email" && typeof value === "string") return "redacted@example.test";
return value;
}
function rowsToMock(rows: ParsedRow[], limit: number, redact: Redactor) {
if (!Number.isInteger(limit) || limit < 1) throw new RangeError("limit 必须是正整数");
const count = Math.min(rows.length, limit);
const result: Array<Record<string, unknown>> = [];
for (let i = 0; i < count; i++) {
const row = rows[i];
const item: Record<string, unknown> = {};
for (let c = 0; c < row.columns.length; c++) {
const name = row.columns[c];
item[name] = redact(name, row.values[c]);
}
result.push(item);
}
return result;
}
console.log(rowsToMock(parsed, 2, redactEmail));六、常见错误方案
假定正则匹配就能解析复杂的 INSERT 语句;把二进制数据直接转为普通字符串导致数据损坏;未对脱敏规则做单元测试导致敏感字段泄露。
七、边界条件:NULL 值、二进制与超长文本
NULL 值不能在 JSON 中隐式转为空字符串;BLOB/CLOB 二进制列应用 Base64 或 Hex 呈现;包含换行与引用的长文本需严格转义。
八、如何验证 Mock 数据完整性
对比 SQL 行数与 JSON 元素数;校验主键唯一性、外键引用、NULL 比例和类型范围,并断言敏感列无法还原为源值。
九、FAQ
问:SQL 中的 DATE 类型如何转 JSON?答:建议转为 ISO 8601 UTC 格式字符串(如 '2026-07-28T00:00:00Z')。
问:可以批量解析上万条 INSERT 吗?答:可以,但需要流式分段处理,避免在内存中构建巨大 DOM 树。
问:如何处理 AUTO_INCREMENT 主键?答:Mock 数据建议保留主键以便反映关联关系,或者在生成阶段使用连续自增整型。
十、总结
SQL dump 转 JSON Mock 是解析、脱敏、转换的多阶段流程。明晰各阶段职责并建立严格的类型转换机制,才能得到安全、干净的测试数据集。
来源与延伸阅读
技术审校所依据的规范与权威参考资料。
- PostgreSQL Documentation — SQL Syntax
PostgreSQL Global Development Group
- RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format
RFC Editor
相关文章
SQL 转 JSON:NULL、布尔值与 0/1 的语义差异
分开说明 PostgreSQL boolean、MySQL TINYINT(1)、SQL NULL、字符串 null 与数值 0/1 在 JSON 转换中的差异,并给出显式映射和验证示例。
错误排查SQL 转 JSON:为什么正则难以可靠解析 INSERT
用最小示例说明正则提取 INSERT 会被引号、转义、批量 VALUES、注释和 SQL 方言打破,并提供仅用于分句的保守扫描器与 parser 选型边界。
最佳实践SQL Formatter 接入 CI/CD:检查、自动修改与失败策略
围绕 SQL 格式化的 CI/CD 接入说明 check、write 两种模式、差异输出和失败策略,避免把格式检查写成泛化工程模板。
继续阅读
可打开关联的浏览器工具,使用自己的样本验证文中的处理流程。
打开关联工具