Navicat 16 无法直接导出 PostgreSQL Schema,需通过“结构同步”生成含依赖顺序和表/列注释的完整 DDL 脚本;字段注释若未用 COMMENT ON 显式声明,则需手动查询 pg_description 补充导出。
Navicat 16 无法直接“导出 Schema”这个概念
postgresql 没有 mysql 那种“数据库=schema”的默认映射,schema 是独立于数据库的逻辑容器。navicat 16 的界面里压根没有「导出 schema」菜单项——你右键点数据库、点表、甚至点模式(schema)本身,都找不到这个选项。所谓“导出 schema”,实际是指导出该 schema 下所有对象(表、视图、函数、序列、类型、注释等)的定义语句,且要保证依赖顺序正确、注释不丢、编码不乱。
必须用「结构同步」生成可执行 DDL,不是「导出向导」
很多人试过右键 schema →「导出向导」→ 选 SQL 格式,结果导出的是空文件,或只有一两条 CREATE SCHEMA,没任何表。这是因为「导出向导」本质是数据导出工具,对 PostgreSQL 的 schema 级对象支持极弱,连 pg_class 和 pg_attribute 都不查,更别说 pg_description 里的字段注释了。
真正可行的路径只有一条:用「结构同步」反向生成 DDL。
- 新建一个空的 PostgreSQL 数据库(哪怕只是临时建在本地),连接它
- 在 Navicat 中打开「工具」→「结构同步」
- 源选择你的目标
schema(注意:不是整个数据库,而是展开后选中具体 schema 名,如public或app) - 目标选刚才建的空库(或任意空 schema)
- 勾选「仅生成脚本」,取消「执行同步」
- 点击「下一步」,Navicat 会自动分析依赖关系(比如先建类型、再建表、最后建函数),生成带
COMMENT ON COLUMN和COMMENT ON TABLE的完整脚本
生成的 SQL 文件里会有类似这样的内容:COMMENT ON COLUMN public.users.email IS '用户注册邮箱'; —— 这才是真正的 schema 元信息落地。
导出字段注释必须手动补查询,Navicat 不自动包含
即使用了结构同步,Navicat 16(截至 2026 年 6 月)仍不会把字段注释(col_description() 返回值)作为 DDL 的一部分写进脚本,除非你在源库中已用 COMMENT ON COLUMN 显式声明过。很多团队靠建表时加 COMMENT,但更多人是在 pg_description 里维护,Navicat 对后者完全无视。
补救办法:在 Navicat 查询窗口中执行这段 PostgreSQL 查询(替换 your_schema_name):
SELECT n.nspname AS schema_name, c.relname AS table_name, a.attname AS column_name, pg_catalog.col_description(c.oid, a.attnum) AS column_comment FROM pg_catalog.pg_attribute a JOIN pg_catalog.pg_class c ON a.attrelid = c.oid JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid WHERE c.relkind = 'r' AND n.nspname = 'your_schema_name' AND a.attnum > 0 AND NOT a.attisdropped ORDER BY n.nspname, c.relname, a.attnum;
然后右键结果集 →「导出向导」→ 选 Excel/CSV,编码务必选 UTF-8(不是 UTF-8 with BOM),否则中文注释变问号。
字符集与权限问题最容易卡住导出流程
导出失败常不是功能限制,而是底层连接没配对:
- 连接属性 →「高级」页 → 勾选「使用 PostgreSQL 字符集」,并确认「客户端编码」设为
UTF8 - 如果查询
pg_description报错permission denied for table pg_description,说明当前用户没权限查系统目录:需 DBA 执行GRANT SELECT ON pg_description TO your_user; - 结构同步生成脚本时若报
type "citext" does not exist,说明目标空库缺扩展,得先在空库里执行CREATE EXTENSION IF NOT EXISTS citext;,否则同步会中断
最常被忽略的一点:Navicat 的「结构同步」只处理对象定义,不导出数据;如果你需要连同 seed 数据一起迁移,得另起一个「数据传输」任务,且必须确保两个任务的执行顺序——先跑结构同步,再跑数据传输,否则建表语句还没执行就插数据,必然报错。











