Navicat导出的.nsx/.psc文件不可用于CI/CD,仅纯文本SQL脚本可集成;需满足导出结构与数据、启用IF NOT EXISTS、禁用DROP、设utf8mb4字符集;须预处理注释、语法、事务及环境适配,并联动XML模型校验。

CI/CD里不能直接调用Navicat GUI导出的.nsx或.psc文件
Navicat生成的.nsx(同步配置)和.psc(备份)都是本地二进制格式,含连接密钥、会话状态、平台指纹等私有元数据,CI服务器上既没GUI环境也无对应Navicat实例,根本无法解析。强行上传到流水线会导致“无法识别文件”或连接超时错误。
真正可集成的只有纯文本SQL脚本,且必须满足三个硬性条件:
- 导出时显式勾选
Export structure和Export data(默认只导结构) - 在「高级」选项中启用
Use IF NOT EXISTS,禁用DROP TABLE(避免误删线上表) - 字符集强制设为
utf8mb4,并确认导出SQL包含SET NAMES utf8mb4或等效声明
Navicat导出的SQL必须预处理才能进CI
Navicat原生导出的SQL不是即插即用的CI资产——它混杂了客户端元信息、注释风格不统一、缺少事务边界、且可能含MySQL专属语法(如ENGINE=InnoDB),直接扔进PostgreSQL或TiDB流水线会报错。
上线前必须做三件事:
- 用
sed或awk剥离所有/* Navicat */类头部注释,只保留/* Exported by: ... */这类可审计行 - 对跨库场景(如MySQL→PostgreSQL),用脚本替换
TINYINT(1)→BOOLEAN、JSON→JSONB、AUTO_INCREMENT→SERIAL - 在文件开头插入
BEGIN; SET statement_timeout = '300s';,结尾加COMMIT;,防止长事务卡死CI节点
如何让Navicat导出脚本适配不同环境(dev/staging/prod)
同一个user_service_v2.sql不能在所有环境无差别执行:dev库允许DROP,prod库必须只ALTER;staging需校验数据一致性,而dev只需建表。
推荐做法是用Navicat导出**基础DDL+DML分离版本**,再由CI按环境注入逻辑:
- 导出时取消勾选
Include DROP TABLE,确保脚本天然支持幂等执行 - 用
grep -E "^(CREATE|INSERT|UPDATE)" user_service_v2.sql > base.sql提取核心语句,剔除USE db_name等环境强绑定指令 - CI中通过
envsubst注入变量:把INSERT INTO ${TABLE_PREFIX}users替换成INSERT INTO staging_users - 对prod环境,在执行前加校验步骤:
psql -c "SELECT COUNT(*) FROM users;" | grep -q "0",非空则中止
团队协作中脚本变更必须和XML模型diff联动
如果团队用Navicat模型工作区(.nmodel)管理结构,但CI只跑SQL脚本,就埋下严重隐患:某人图形界面改了字段注释,导出SQL却没带-- @desc,Git里看不出变更,但下游BI工具因缺失注释报错。
必须建立双轨校验机制:
- 每次提交SQL脚本,CI自动运行
navicat-cli --export-xml --source models/user_service_v2.nmodel生成user_service_v2.xml - 用
git diff --no-index old.xml new.xml | grep -E "<column wc>统计结构变更行数,大于0才允许合并</column> - 禁止任何绕过XML直接修改
.nmodel后导出SQL的行为——这等于跳过评审,下次同步可能把开发库的JSON字段推到MySQL 5.7生产库上直接失败
实际落地最常被忽略的是:Navicat导出的SQL默认不包含SET sql_mode,而CI服务器MySQL配置往往启用了STRICT_TRANS_TABLES,导致导入时因NULL插入非空字段静默失败。必须在导出高级选项里手动勾选「兼容MySQL 5.7+」,或CI中执行前加SET sql_mode='';。


















