# 数据库迁移插件 **Repository Path**: godbirds/dsh-datatransfer ## Basic Information - **Project Name**: 数据库迁移插件 - **Description**: DSH数据库迁移插件(DeepSeek Harness) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-26 - **Last Updated**: 2026-08-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 🗄️ dsh-datatransfer > **数据库迁移插件(DeepSeek Harness)** > > 常用数据库(Oracle / MySQL / PostgreSQL / 达梦 DM / SQLite)任意组合**跨库迁移**:表结构、数据、索引/约束、序列、视图、同义词、存储过程、函数、包、触发器、授权、表/列注释。 > **同方言**(Oracle↔Oracle、Oracle↔达梦、MySQL↔MySQL、PostgreSQL↔PostgreSQL)高保真透传源 DDL(DBMS_METADATA / SHOW CREATE / pg_get_functiondef);**跨方言**经「逻辑类型」映射翻译(含主键/外键/索引/序列/注释/自增映射)。 > 数据**批量迁移**(keyset 分页 + 批量绑定 + 表级并发),实时日志 + 迁移总结报告。 ## 🚀 功能特性 | 模块 | 能力 | | --- | --- | | 数据源 | 源库 A / 目标库 B 双卡片配置(主机/端口/服务名/SID/用户/密码/字符集),一键「测试连接」,密码脱敏存储;旧版 Oracle(12.1 之前)可开启 **Instant Client 厚模式** | | 数据源缓存 | 底部半透明「🗂️ 数据源缓存 ⬆」胶囊按钮,点击展开底部抽屉;配置保存后自动写入缓存文件 `.cache.datasource.json`(fingerprint 去重,同一条=更新);支持一键「载入到 A/B」、删除单条、清空全部;密码仅在后端流转 | | 注释迁移 | 表/列注释随迁移保留:Oracle/达梦/PostgreSQL 目标用 `COMMENT ON`,MySQL 目标表注释用 `ALTER TABLE ... COMMENT`(列注释因需 MODIFY 会重置列属性暂跳过);SQLite 无原生注释自动跳过 | | 界面设置 | 「⚙️ 设置」按钮常驻插件**顶部栏(📋 任务按钮左侧)**,任意页面可打开对话框自定义插件入口位置(侧边栏底部 / 会话标题栏动作行 / 输入框工具行右侧)与排列顺序,保存后刷新页面生效 | | 迁移范围 | 默认**全量对象**;可勾选:表结构、数据、存储过程、函数、索引/约束、序列、视图、同义词、包、触发器、授权 | | 数据迁移 | ROWID keyset 分页(无主键表也适用)、executeMany 批量绑定(batchErrors 隔离坏行)、每批 commit、表级并发(默认 4) | | 保真 | DBMS_METADATA 提取 DDL(失败自动回退元数据重建);高精度 NUMBER 按字符串传输防丢位;TIMESTAMP_TZ/INTERVAL 统一格式往返;CLOB/NCLOB/BLOB 就地转 JS 值防乱码 | | 目标策略 | 同名表「跳过 / 保留追加 / 重建(DROP 后重建)」三种可选 | | 顺序 | 建表 → 数据 → 索引 → 约束(FK 拓扑序)→ 序列 → 视图/同义词 → 函数/过程/包 → 触发器 → 授权 → 行数校验 → 统计信息 | | 实时日志 | GUI 每 600ms 增量拉取,分级着色滚动;日志同时落盘 `tasks/.log` | | 总结报告 | 迁移结束自动生成 Markdown 报告(对象统计/数据明细/校验结果/错误清单),可预览、复制、下载;报告落盘 `reports/-迁移报告-*.md`;预览支持 **Markdown 自动渲染**(标题/表格/列表/代码,零第三方依赖);「打印下载」经浏览器打印导出(可直接打印或另存为 PDF,零依赖,导出文件名为「数据库迁移总结报告-任务ID」) | | 任务列表 | 插件页右上「📋 任务」按钮 → 右侧抽屉列出全部迁移任务(任务ID / 状态 / 开始时间 / 结束时间 / 删除,运行中禁删;「+ 新建迁移」回向导);点击任务进入 4 节点详情页(数据源配置 / 迁移配置 / 执行迁移 / 总结报告):已完成任务默认定位「总结报告」可直接下载报告,配置为只读快照、日志从磁盘重放,**顶部步骤条可点击、节点间可上一步/下一步双向导航**;历史任务从 `.tasklist.json` 持久化,**DSH 重启后仍可回看日志、下载总结报告**,支持多任务并发 | | 跨库迁移 | Oracle / MySQL / PostgreSQL / 达梦 DM / SQLite 任意组合互迁(表结构/数据/主键/外键/索引自动映射,列类型经「逻辑类型」翻译层生成目标 DDL;单列数字主键自动映射目标自增:MySQL `AUTO_INCREMENT` / PostgreSQL `SERIAL`);SQL Server 预留 | ## 📦 安装 > **为什么安装会多一步?** 本插件依赖原生驱动 `oracledb`(Oracle,必需)与 `odbc`(达梦,可选)。 > pnpm ≥ 10.1 为供应链安全**默认禁止依赖在安装时执行构建脚本**,pnpm 11 更会以退出码 1 中断安装, > 并跳过 DSH 的 `reconcilePlugins` —— 结果是插件只按「纯客户端」挂载、进不了 `dsh.profile.bundles`, > Host 端 `/datatransfer` RPC 不生效(“装了未生效”)。因此安装本插件**必须**先放行这两个构建脚本; > 下文四种方式均已覆盖,任选其一即可。 > > 环境要求:已安装 DSH(web profile)、Node.js ≥ 18、pnpm ≥ 10.1(11 兼容)。 ### 方式一:市场 UI 安装(推荐给最终用户) > 前提:插件已收录进 DSH 市场目录(见文末「如何让插件出现在市场」)。未收录时市场搜不到,请改用方式二/三。 1. 打开 DSH → **设置 → 市场**; 2. 搜索 `dsh-datatransfer`(或浏览「插件市场」分类)找到卡片; 3. 点「**安装**」→ 确认对话框会显示来源与安装命令 → 「**确认安装**」; 4. 若弹出「**允许构建脚本并重试**」横幅:点击它(市场会自动把 `oracledb: true` / `odbc: false` 写入 `allowBuilds` 并重试); 5. 看到「已安装 · 刷新页面后生效」后:**完全退出并重启 DSH**,浏览器 **Ctrl+F5 硬刷新**; 6. 侧边栏底部出现「🗄️ 数据迁移」即成功。 ### 方式二:一键脚本(推荐给能拿到插件源码的人) 先获取插件源码(`install-to-dsh.mjs` 就在仓库里),再在**插件根目录**执行(幂等,可反复运行): ```bash git clone https://gitee.com/godbirds/dsh-datatransfer.git cd dsh-datatransfer node install-to-dsh.mjs # 安装到默认 web profile node install-to-dsh.mjs --with-odbc # 需要达梦(DM8 ODBC)时额外放行 odbc 构建 node install-to-dsh.mjs --dsh-cli # 可选:先走 DSH 官方 CLI(如 ../deepseek-harness-master) DSH_PROFILE= node install-to-dsh.mjs # 安装到其它 profile ``` 脚本自动完成:① 修复 `~/.dsh/profiles/web/pnpm-workspace.yaml` 的 `allowBuilds` (占位符 → 布尔值,`oracledb: true`、`odbc: false`);② 确保 `dependencies` 含 `dsh-datatransfer`; ③ 在 profile 内执行 `pnpm install`(oracledb 自动下载 N-API 预编译二进制); ④ 兜底把 `dsh-datatransfer` 写入 `dsh.profile.bundles`;⑤ 打印重启指引。 完成后:**完全退出并重启 DSH**,浏览器 **Ctrl+F5 硬刷新**。 ### 方式三:DSH 官方 CLI ```bash # ⚠️ 必须从 DSH CLI 源码仓库目录运行(`dsh` 是该工作区注册的 pnpm 插件); # 不要在插件仓库目录内运行——pnpm 11 会先检查当前目录依赖,插件仓库自身声明的 # oracledb/odbc 会被构建拦截拦下(ERR_PNPM_IGNORED_BUILDS)。 cd # 例如 deepseek-harness-master # 仓库安装 pnpm dsh plugin --profile web add https://gitee.com/godbirds/dsh-datatransfer.git # 本地安装 pnpm dsh plugin --profile web add "file:D:\WORKSPACE\AI-WORK\deepseek-harness-plugins\plugins\dsh-datatransfer" # ④ 完全退出并重启 DSH,浏览器 Ctrl+F5 硬刷新 ``` 若报 `[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: odbc@…, oracledb@…`: 1. 编辑 `~/.dsh/profiles/web/pnpm-workspace.yaml`,把 `allowBuilds` 里的占位符 `set this to true or false` 改成下面的布尔值(见「构建脚本拦截」小节); 2. 重新执行上面的 `pnpm dsh plugin ... add` 命令; 3. 确认 `~/.dsh/profiles/web/package.json` 的 `dsh.profile.bundles` 含 `dsh-datatransfer`(不在则手动追加); 4. **完全退出并重启 DSH**,浏览器 **Ctrl+F5 硬刷新**。 ### 方式四:手动安装(备用 / 本地开发) ```bash # ① 放行构建脚本:编辑 ~/.dsh/profiles/web/pnpm-workspace.yaml,见「构建脚本拦截」小节 # ② 安装(二选一:本地副本 or git 源) pnpm --dir ~/.dsh/profiles/web add "file:D:\WORKSPACE\AI-WORK\deepseek-harness-plugins\plugins\dsh-datatransfer" pnpm --dir ~/.dsh/profiles/web add https://gitee.com/godbirds/dsh-datatransfer.git # git 源 # ③ 编辑 ~/.dsh/profiles/web/package.json,在 dsh.profile.bundles 末尾追加 "dsh-datatransfer" # ④ 完全退出并重启 DSH,浏览器 Ctrl+F5 硬刷新 ``` ### 安装后验收 - 侧边栏底部出现「🗄️ 数据迁移」入口; - 设置 → 插件 → dsh-datatransfer 状态为 **bundle 层加载**(而非「纯客户端插件」); - 打开「数据迁移」→ 配置数据源 →「测试连接」成功(说明 `/datatransfer` RPC 已通)。 ### 构建脚本拦截(pnpm 11)详解 - **为什么拦**:pnpm ≥ 10.1 默认禁止依赖在安装时执行 `install`/`postinstall`/`prepare` 脚本; `oracledb`、`odbc` 恰带 install 脚本(下载/编译原生二进制),首次安装必被拦。 - **占位符 bug**:被拦时 pnpm 会在 `pnpm-workspace.yaml` 自动写入字面值 `set this to true or false` (pnpm#11535),必须手工改成布尔值,否则后续安装继续失败。 - **正确配置**(`~/.dsh/profiles/web/pnpm-workspace.yaml`): ```yaml allowBuilds: oracledb: true # 必需:下载 N-API 预编译二进制,thin 模式免装 Oracle 客户端 odbc: false # 达梦专用;需要达梦时改 true 或运行 install-to-dsh.mjs --with-odbc ``` - **oracledb 不能省**:Oracle 迁移是核心功能,thin 模式同样需要 install 脚本下载的预编译二进制; 该构建无需本机安装 Oracle 客户端,放行安全。odbc 仅达梦使用,默认跳过构建不影响其它库。 ### 常见安装问题 | 现象 | 处理 | | --- | --- | | `ERR_PNPM_IGNORED_BUILDS` | 见「构建脚本拦截」小节;或直接运行 `node install-to-dsh.mjs` | | 市场显示「纯客户端插件」/装了未生效 | `dsh.profile.bundles` 缺 `dsh-datatransfer`(构建被拦致 reconcile 未执行):运行 `node install-to-dsh.mjs` 或手动追加后重启 | | `pnpm dsh` 报 `Command not found` | 需在 DSH CLI 源码仓库目录运行(见方式三 ⚠️) | | 安装卡在 oracledb 下载 | 预编译二进制自 GitHub 下载,网络不佳时重试或配置代理;成功后日志显示 `Node-oracledb 6.10.0 installed` | | 需要达梦 | 运行 `node install-to-dsh.mjs --with-odbc`,并确认本机装有 DM8 ODBC 驱动 | ### 如何让插件出现在市场(作者向) 市场 UI 安装的是**策展目录**里的插件(`awesome-dsh-plugin.com` 的 `plugins.json`,中国区经 npm 包 `dsh-plugin-catalog` 分发),**没有“粘贴 git 地址”的入口**。要让最终用户能在市场 UI 一键安装: 1. 打开 → 顶部 **Submit**(提交)→ 按目录仓库指引提交收录 (条目格式 `owner/repo` 或 `owner/repo#path`;gitee 源建议同时提供 GitHub 镜像或发布 npm 包); 2. 收录生效后,最终用户即可按「方式一」在市场 UI 安装。 ## 🚀 快速上手 1. 进入插件(入口默认在 DSH 侧边栏底部「🗄️ 数据迁移」,可在插件顶部栏「⚙️ 设置」中调整入口位置与顺序); 2. **数据源配置**:填源库 A / 目标库 B(Oracle / MySQL / PostgreSQL / 达梦 / SQLite 任意组合互迁;Oracle/达梦填服务名/SID,MySQL/PostgreSQL 填 database,PostgreSQL 可填 schema,SQLite 填数据库文件路径;达梦需本机安装 DM8 ODBC 驱动)→ 分别「测试连接」→「保存数据源配置」(自动加入数据源缓存);点击底部半透明「🗂️ 数据源缓存 ⬆」展开抽屉,可一键载入历史数据源、删除单条或清空缓存; 3. **迁移配置**:默认全量对象;可勾选迁移范围、调整批大小/并发数、选目标同名表策略;「刷新」对象预览可勾选仅迁移部分表;跨库时页面会提示「视图/例程/触发器/授权将跳过」; 4. **执行迁移**:「开始迁移」→ 实时日志滚动 + 进度条 + 迁移行数;可随时「停止」; 5. **总结报告**:报告预览 →「下载报告 .md」或「复制内容」; 6. **任务回看**:插件页右上「📋 任务」→ 右侧抽屉查看全部迁移任务(运行中 / 已完成,可删除;「+ 新建迁移」回向导);点击任务进入 4 节点详情页——已完成任务默认停在「总结报告」可直接下载报告,配置为只读快照、日志从磁盘重放,顶部步骤条可点击、节点间可上一步/下一步双向导航;任务信息持久化在 `.tasklist.json`,重启 DSH 后仍可查看,也可删除任务(连带清理日志与报告文件)。 ## 📂 架构 ``` dsh-datatransfer/ ├── src/ # Host 端(Node):面向对象分层 │ ├── index.js # 插件入口:装配 + 模型工具 + RPC 挂载 │ ├── app.js # 组合根(Config → Migration → AdapterFactory) │ ├── rpc.js # /datatransfer/* RPC(任务 start/status/poll/stop/report) │ ├── tools.js # 5 个 datatransfer_* 模型工具 │ ├── core/ # config(配置脱敏)/ log-buffer(日志)/ report(报告)/ sql-util │ ├── adapters/ # DatabaseAdapter 接口 + type-map(逻辑类型映射)+ oracle/mysql/postgres/dm/sqlite 适配器 + mssql stub │ ├── engine/ # migrator 编排 / ddl / data(批量)/ routine / verify │ └── services/ # MigrationService(任务状态机 + 日志落盘 + 历史) ├── frontend/ # Vue3 + Element Plus 工程(构建产物为 client.js) ├── client.js # 构建产物(CSS + Vue IIFE + React 桥接壳,勿手改) ├── test/ # Mock 内存库全流程测试 + client 沙箱检查 ├── builder.mjs # 一键发布:release.mjs + sync-to-dsh.mjs ├── install-to-dsh.mjs # 一键安装/修复到 DSH profile(放行构建脚本 + 写入 bundles) └── release.mjs # 重建 + 全量验证 ``` GUI 经同源 `fetch('/datatransfer/*')` 访问 Host 端 webServer 路由。 ## 💻 本地开发 / 发布 ```bash cd frontend && npm install && npm run build # 重建 client.js node release.mjs # 构建 + 全量验证(35 项断言) node builder.mjs # 构建验证 + 同步副本到 DSH ``` 发布后:完全退出并重启 DSH,浏览器 Ctrl+F5 硬刷新。 ## 🛠 测试 | 文件 | 覆盖 | | --- | --- | | `test/engine.test.mjs` | 全量迁移端到端 / 错误隔离 / 目标策略 / 范围过滤 / includeTables / 分页 / 停止 | | `test/core.test.mjs` | 配置脱敏与密码保护(含 ui 入口位置配置)/ 日志缓冲 / SQL 工具 / 报告生成 | | `test/rpc.test.mjs` | RPC 全流程(Mock 适配器注入) | | `test/type-map.test.mjs` | 跨库逻辑类型映射(源类型→逻辑类型→目标 SQL 类型、精度/长度换算) | | `test/cross-db.test.mjs` | 跨库端到端:Oracle↔MySQL、Oracle→PostgreSQL、PostgreSQL→MySQL、Oracle↔达梦(同方言族透传)、小写表名部分迁移 | | `test/sqlite.test.mjs` | SQLite 真实集成(node:sqlite):Oracle→SQLite 类型映射/主键内联、SQLite→MySQL、大批量分批、自增映射 | | `test/check-client.mjs` | client.js 无 process 浏览器沙箱执行 + 注册 | | `test/tool-schema-check.mjs` | 工具 schema 无 undefined | > 本机无需 Oracle 即可运行全部测试(Mock 内存库);真实迁移请用 GUI「测试连接」+ 小表试迁验证。 ## ❓ 常见问题 | 问题 | 处理 | | --- | --- | | 「测试连接」失败 | 检查主机/端口/服务名(SID)/用户名密码;目标机能否 telnet 1521;oracledb 是否随 bundle 安装成功 | | 连接报 NJS-138(旧库不支持) | 源/目标库为 Oracle 12.1 之前版本,thin 模式不支持:在数据源表单开启「旧库兼容(厚模式)」并填 **Oracle Instant Client** 目录(需本机安装 Instant Client) | | 连接报 ORA-01017 | 用户名/口令无效,请核对数据源 B 的口令与账号状态 | | DBMS_METADATA 提取失败 | 插件会自动回退「元数据重建」建表/提取 ALL_SOURCE 源码;若需完整 DDL 保真,源库账号需可执行 DBMS_METADATA | | 序列值不对齐 | 默认在 12c+ 上自动 `ALTER SEQUENCE ... RESTART` 对齐;11g 不支持时报告会提示手工核对 | | 出现乱码 | 源/目标字符集与客户端字符集不同时,文本按 Unicode 传输通常不乱码;如个别列异常,请核对目标库 `NLS_CHARACTERSET` | | 迁移中途想停 | 执行页「停止」,当前批次结束后优雅停止,已迁移数据保留 | | 跨库时视图/例程/触发器丢了 | 跨方言无法自动翻译方言代码,默认跳过并在报告列出;同方言(含 Oracle↔达梦、PG↔PG)完整迁移;请按报告提示人工改写后补建 | | 达梦连接失败 | 确认本机已安装 DM8 ODBC 驱动、插件 optional 依赖 `odbc` 编译成功,并在数据源表单选择「达梦 DM(需 ODBC)」 | | 安装报 ERR_PNPM_IGNORED_BUILDS | pnpm 11 拦截构建脚本:把 `~/.dsh/profiles/web/pnpm-workspace.yaml` 的 allowBuilds 占位符 `set this to true or false` 改成 `oracledb: true`、`odbc: false` 后重装;或直接 `node install-to-dsh.mjs` | | 市场显示「纯客户端插件」/装了未生效 | `dsh.profile.bundles` 缺 `dsh-datatransfer`(多半是安装时构建脚本被拦、reconcile 未执行):运行 `node install-to-dsh.mjs` 或手动追加后重启 | ## 📚 相关文档 | 文档 | 说明 | | --- | --- | | [docs/需求设计文档.md](docs/需求设计文档.md) | 需求基线、功能与验收 | | [docs/开发实现说明.md](docs/开发实现说明.md) | 架构、引擎设计、适配层扩展指南 | ## ⚠️ 已知边界 - **XMLType / 对象类型列 / 空间数据**:标记「尽力而为」,失败进入错误清单不阻断整体; - **大 LOB**:按 fetchAsString/fetchAsBuffer 整块读入内存,超大 LOB 表请评估内存(`maxLobBuffer` 仅做告警阈值); - **视图/函数等 DDL** 依赖源 schema 中的其它对象:目标 schema 不同时,插件会自动替换 DDL 中的 `"源OWNER".` 前缀,但若被引用对象在目标库不存在,创建会失败(进入错误清单); - **跨方言**(如 Oracle→MySQL):视图/同义词/函数/过程/包/触发器/授权因方言代码无法自动翻译而跳过(报告与前端提示);PG→PG 同方言可迁移例程/触发器; - **PostgreSQL 建表**:走元数据重建(PG 无 SHOW CREATE),分区表/生成列/PG 特有默认值表达式丢失,建议 `pg_dump` 复核; - **MySQL 目标列注释**:因 `MODIFY COLUMN` 会重置列属性暂跳过;**SQLite** 无原生注释自动跳过; - **达梦(ODBC)**:`odbc` 为 optionalDependencies,需本机安装 DM8 ODBC 驱动并编译成功,否则选择达梦会得到安装指引(不影响其它库);ROWNUM/参数绑定待真实环境实测; - **SQL Server**:类型下拉预留置灰,后续版本实现。