根本原因是Navicat 17导出时跳过JSON序列化,将jsonb字段当作普通text处理,导致反斜杠等字符被双重转义;必须用jsonb_pretty()等PostgreSQL函数在服务端完成标准JSON渲染,或改用COPY命令、脚本直连导出。

Navicat 17 对 JSONB 字段不做转义感知,直接输出原始字符串
根本原因不是 PostgreSQL 存错了,而是 Navicat 17 在导出时完全跳过了 JSON 序列化流程。它把 jsonb 字段当成普通 text 类型读取——比如数据库里存的是 {"path": "C:\temp\file.txt"}(合法 JSON),Navicat 却按字面量拼接成 {"path": "C:\\temp\\file.txt"},导致反斜杠翻倍。
PostgreSQL 的 jsonb_pretty() 能绕过这个缺陷
必须让 PostgreSQL 自己完成最终渲染,不能依赖 Navicat 的字段拼接逻辑。用 jsonb_pretty() 强制走标准 JSON 编码路径,它会正确处理双引号、换行、反斜杠等所有转义规则。
- 导出单字段:
SELECT jsonb_pretty(data) FROM my_table; - 导出带其他列的完整对象:
SELECT id, jsonb_pretty(metadata) AS metadata FROM my_table; - 若需嵌入到外层 JSON 中:
SELECT jsonb_build_object('id', id, 'data', jsonb_pretty(metadata)) FROM my_table;
别信导出向导里的“JSON 格式”选项
选了 JSON 格式 ≠ 字段内容是合法 JSON。这个选项只控制外层结构(比如是否每行一条记录),对字段内部的字符串不做任何转义处理。尤其当字段值含
、"、中文或 \ 时,导出后几乎必然报 SyntaxError: Unexpected token。
- Mac 版默认不勾选「使用双引号包裹字段名」,导出结果形如
{id:1,name:"张三"}—— 这根本不是 JSON - 即使勾选了该选项,也无法修复
jsonb字段内部的双重转义问题 - 字段含
\的典型表现:原始值"C: emp"→ 导出为"C:\\temp"→json_decode()失败
真正安全的导出路径只有两条
要么用 SQL 预处理让 PostgreSQL 输出标准 JSON 文本,要么彻底弃用 Navicat 的 JSON 导出功能,改用 COPY 命令或脚本直连。
COPY (SELECT jsonb_pretty(jsonb_col) FROM t) TO '/tmp/out.json' WITH (FORMAT text);- 用 Python +
psycopg2执行相同查询,逐行写入文件,确保编码和换行可控 - 千万别依赖 Navicat 自动推导字段类型——它对
jsonb和text不做区分,也不调用to_jsonb()或jsonb_strip_nulls()等函数
json_parse() 或打开文件检查原始字符时,才会暴露双重转义。


















