使用sqldump-to工具时列头偏移及JSON5解析错误排查
使用sqldump-to转换MySQL转储为JSON时的解析错误与列错位问题
我用arjunmehta开发的sqldump-to工具将MySQL的SQL转储转换成JSON格式,用于导入BigQuery。运行工具处理数据表时,命令行反复抛出字符串解析失败错误,但仍生成了输出文件。输出文件存在以下异常:
- 列名整体右移
- 首列名称固定为"["
- 最后一列名称丢失,末列值被关联到前一列名称上
我对JavaScript不熟悉,无法自行调试,恳请协助排查问题。
命令行错误日志(重复出现,lineNumber始终为1,columnNumber变化)
Unable to parse string ['US','USD','Spring',2023,'2022-12-09','S23 AMA Supercross VLP 9-Dec-22.xlsx','SUPERCROSS',NULL,'','','REFRESH',null,'DIE CAST','Vehicles','65702','6066278',null,'GML ',null,'1:24 Die Cast - NEON Solid Pack',4.49,'SOLID (omni compliant)','YES',null,null,'GLOBAL','NO','No','No',null,null,'1 die cast bike w/ attached rider,1 race gate stand, 1 collector poster ',5,'Blister Card','Yes','4+','NO','Vietnam',null,null,'ON SHELF:1/1/2023',null,null,0.00,0.00,0.00,'2023-07-11'] SyntaxError: JSON5: invalid character 'U' at 1:93 at syntaxError (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\node_modules\json5\lib\parse.js:1110:17) at invalidChar (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\node_modules\json5\lib\parse.js:1055:12) at literal (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\node_modules\json5\lib\parse.js:722:19) at Object.value (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\node_modules\json5\lib\parse.js:298:13) at lex (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\node_modules\json5\lib\parse.js:100:42) at Object.parse (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\node_modules\json5\lib\parse.js:25:17) at SQLSignalParserWriter.handleData (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\lib\sql-signal-parser-writer.js:73:28) at Transform.<anonymous> (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\lib\write-worker-child.js:11:12) at Transform.emit (node:events:517:28) at addChunk (C:\Users\xxx\AppData\Roaming\npm\node_modules\sqldump-to\node_modules\readable-stream\lib\_stream_readable.js:279:12) { lineNumber: 1, columnNumber: 93 }
输出数据示例
{"[":"US","Country":"USD","Currency":"Spring","Season":2023,"Year":"2022-10-24","File_Date":"S23 MNJ_MJC VLP 24-Oct-22.xlsx"
输出schema文件示例
[ { "name": "[" }, { "name": "Country", "type": "varchar(10)" }, { "name": "Currency", "type": "varchar(10)" },
执行的命令
mysqldump --column-statistics=0 -u uname -p -h hostname price vlp_raw | sqldump-to -d C:\Users\xxxx\Downloads\output --schema
问题分析与解决建议
问题根源
sqldump-to内部使用JSON5解析MySQL转储中的INSERT值列表,但MySQL的语法和JSON5不兼容:
- MySQL用单引号包裹字符串,而JSON5要求必须用双引号
- MySQL中的空值是大写
NULL,JSON5要求小写null
解析失败后,工具的列值映射逻辑出错,导致列名偏移、首列异常等问题。
解决方法
预处理转储输出,修正语法兼容问题
在管道中加入字符串替换步骤,将MySQL语法转换为JSON5兼容格式:- Windows PowerShell执行命令:
mysqldump --column-statistics=0 -u uname -p -h hostname price vlp_raw | ForEach-Object { $_ -replace "'", '"' -replace 'NULL', 'null' } | sqldump-to -d C:\Users\xxxx\Downloads\output --schema - Linux/macOS执行命令:
mysqldump --column-statistics=0 -u uname -p -h hostname price vlp_raw | sed "s/'/\"/g; s/NULL/null/g" | sqldump-to -d ~/Downloads/output --schema
- Windows PowerShell执行命令:
处理特殊字符干扰
如果数据中存在未转义的双引号、换行符等特殊字符,会进一步导致解析失败。可以在mysqldump时添加--hex-blob参数,将二进制/特殊数据转为十六进制,避免干扰:mysqldump --column-statistics=0 --hex-blob -u uname -p -h hostname price vlp_raw | sed "s/'/\"/g; s/NULL/null/g" | sqldump-to -d ~/Downloads/output --schema替代方案(若上述方法无效)
直接绕过sqldump-to,用Python脚本读取MySQL数据并导出为标准JSON:import pymysql import json # 数据库连接配置 conn = pymysql.connect(host='hostname', user='uname', password='your_password', db='price') cursor = conn.cursor() # 查询数据 cursor.execute("SELECT * FROM vlp_raw") columns = [desc[0] for desc in cursor.description] rows = cursor.fetchall() # 转换为JSON格式 json_data = [dict(zip(columns, row)) for row in rows] # 写入文件 with open('C:\\Users\\xxxx\\Downloads\\output\\vlp_raw.json', 'w', encoding='utf-8') as f: json.dump(json_data, f, indent=2, default=str) # 生成schema(适配BigQuery) schema = [] for desc in cursor.description: col_name = desc[0] col_type = desc[1] # 映射MySQL类型到BigQuery类型,可根据实际调整 bq_type = 'STRING' if col_type in [pymysql.STRING, pymysql.TEXT] else 'INTEGER' if col_type in [pymysql.NUMBER] else 'FLOAT' if col_type == pymysql.FLOAT else 'TIMESTAMP' if col_type == pymysql.DATETIME else 'STRING' schema.append({"name": col_name, "type": bq_type}) with open('C:\\Users\\xxxx\\Downloads\\output\\vlp_raw_schema.json', 'w', encoding='utf-8') as f: json.dump(schema, f, indent=2) cursor.close() conn.close()
内容的提问来源于stack exchange,提问作者Krish
相关产品推荐
相关产品推荐

