navicat 同步 postgresql 数组字段报错,因其 ddl 生成逻辑未解析 pg_type.typarray 等元数据,仅做简单类型名映射,导致缺失“[]”或错误拼写 array,须人工修正脚本或改用 pg_dump/psql。
navicat 同步 postgresql 数组类型字段时的报错,和 datlastsysoid 那类系统表字段缺失问题无关,而是源于其 ddl 生成逻辑对数组语法的硬编码限制——它默认把数组列当作普通标量处理,导致 create table 或 alter table 语句中缺少方括号 [],或错误地将 array 关键字拼成不合法形式。
为什么 Navicat 会把 array 类型同步成错误 DDL?
Navicat(尤其是 16.2 以下版本)在反向工程(Reverse Engineering)或结构同步(Structure Synchronization)过程中,并未完整解析 PostgreSQL 的 pg_type 和 pg_attribute 中关于 typarray 和 attndims 的元数据。它依赖简单的类型名映射,比如看到 text 就写 text,但不会主动补上 text[];看到 integer[] 可能被截断为 integer,或误判为非法类型而跳过。
- 典型错误现象:同步后目标表中该列为
text而非text[],插入数组值时报ERROR: column "xxx" is of type text but expression is of type text[] - 另一常见表现:Navicat 在“同步脚本预览”里显示
ALTER TABLE ADD COLUMN tags ARRAY—— 缺少元素类型,PostgreSQL 拒绝执行 - 根本原因不是驱动协议层问题,而是 GUI 工具层对 PostgreSQL 数组语法建模缺失
手动修正同步脚本中的 array 类型定义
当 Navicat 生成的同步 SQL 明显漏掉 [] 或写错 ARRAY 形式时,必须人工干预。关键不是改 Navicat 设置,而是拦截并重写它输出的 DDL。
- 在 Navicat 的“结构同步”窗口点击“下一步”后,务必点开“查看脚本”按钮,不要直接执行
- 查找形如
tags text、roles character varying的列定义,将其改为tags text[]、roles character varying[] - 若出现
tags ARRAY这种不带元素类型的写法,必须补全为tags text[](不能留ARRAY单独存在) - 对
ALTER TABLE ... ADD COLUMN语句同样处理;对ALTER TABLE ... ALTER COLUMN ... TYPE,确保新类型含[],例如TYPE text[] USING tags::text[]
用 pg_dump + psql 绕过 Navicat 的数组解析缺陷
如果同步涉及大量数组字段或需保证 100% 类型保真,放弃 Navicat 的图形化同步功能更可靠。直接用 PostgreSQL 原生命令导出/导入结构,完全规避其类型映射逻辑。
- 在源库执行:
pg_dump -s -t your_table_name your_db_name > schema.sql(-s只导结构,-t指定表) - 检查
schema.sql中数组列是否正确写为tags text[]—— PostgreSQL 自己生成的 DDL 总是准确的 - 在目标库执行:
psql -d target_db_name -f schema.sql - 注意:此法不处理 Navicat 特有的扩展属性(如注释、索引名前缀),但数组类型零误差
真正容易被忽略的点是:Navicat 的“结构同步”功能本质上是“类型名字符串匹配+启发式修正”,它不读取 pg_type.typarray OID 关联,也不调用 format_type() 函数做标准化输出。哪怕你给列加了 COMMENT ON COLUMN 提示它是数组,它也视而不见。所以凡涉及 jsonb[]、uuid[]、多维数组等复杂场景,脚本介入或原生命令是唯一稳解。











