navicat premium 16 支持本地 sqlite 数据库结构比对,要求均为未加密的本地 .db 文件、使用绝对路径、关闭所有编辑器标签页,并注意其 ddl 生成限制(如不支持删列)、外键需手动启用及 sqlite_sequence 需同步后手动更新。

Navicat Premium 16 支持直接比对两个 SQLite 数据库的结构,但必须确保两者都是本地文件(.db),且不能是内存数据库或加密数据库(如 SQLCipher)——否则会报错 unable to open database file 或 file is encrypted or is not a database。
确认两个 SQLite 数据库都可被 Navicat 正确识别
Navicat 对 SQLite 的结构比对依赖于实际读取 sqlite_master 表和 PRAGMA 输出。如果连接失败,比对功能根本不会出现:
- 检查两个数据库文件路径是否为**绝对路径**,不含中文、空格或特殊符号(如
C:\dev\myapp\prod.db安全,C:\我的项目\data.db易出问题) - 右键连接 → “测试连接”,成功后才继续;若失败,常见原因是:
database is locked(有其他进程正写入)、not a database(文件损坏或非 SQLite 格式)、或权限不足(尤其在 macOS/Linux 的/tmp下) - SQLite 不支持远程连接,所以“源”和“目标”都必须是本地文件连接,类型选
SQLite3,不是SQLite(旧版选项,已弃用)
启动结构同步前必须关闭所有编辑器和数据标签页
Navicat 在执行结构比对时会锁定数据库文件的 schema 读取通道。如果某个表正被打开在“数据查看器”或“设计表”窗口中,比对会卡在“正在加载对象…”或直接跳过该表:
- 关闭所有已打开的
数据、设计表、SQL 编辑器标签页(哪怕只是只读) - 不要在比对过程中切换到其他连接或执行
PRAGMA命令(例如PRAGMA journal_mode) - 如果目标库已有同名表但结构不同,Navicat 默认不会自动重命名或备份原表——它只会生成
ALTER TABLE ... RENAME TO或DROP TABLE语句,这些操作不可逆
比对结果里哪些 DDL 变更 Navicat 实际能生成
SQLite 的 ALTER TABLE 能力有限,Navicat 会根据语法兼容性决定是否生成对应语句,而不是照单全收你的差异:
- ✅ 支持:添加列(
ALTER TABLE t ADD COLUMN c TEXT)、重命名表(ALTER TABLE t RENAME TO t_new)、重命名列(需 SQLite ≥ 3.25.0,Navicat 16 默认启用) - ❌ 不支持(Navicat 会跳过或报黄标警告):删除列、修改列类型、添加/删除主键或 CHECK 约束——此时它会建议你手动导出数据 → 删除旧表 → 创建新表 → 导入数据
- ⚠️ 注意外键:即使你勾选了
PRAGMA foreign_keys = ON,Navicat 结构同步默认不检查外键约束是否生效;若源库启用了外键而目标库没开,同步后的表虽结构一致,但外键实际不生效
部署前务必手动检查生成的 SQL 脚本
点击“部署”按钮后,Navicat 会弹出一个只读的 SQL 预览窗口。这不是装饰——它决定了你是否会丢数据:
- 重点看是否有
DROP TABLE、CREATE TABLE ... AS SELECT或大段INSERT INTO ... SELECT——这些意味着 Navicat 认为无法就地修改,要重建表 - 检查时间戳字段是否被误转成
NUMERIC(SQLite 没有原生 datetime 类型,Navicat 有时会把 TEXT 存储的'2025-01-01'错判为数值) - 如果目标库已有数据,而脚本里含
INSERT OR REPLACE,确认你真需要覆盖——Navicat 不做行级冲突检测,它只按 DDL 差异走
最易被忽略的一点:Navicat 的结构同步不处理 sqlite_sequence 表(自增主键计数器)。如果你同步了带 INTEGER PRIMARY KEY AUTOINCREMENT 的表,目标库的下一条插入可能从 1 开始重复,而非接续源库最大值。这事前无法预判,只能同步后手动 UPDATE sqlite_sequence SET seq = ? WHERE name = 'table_name'。











