达梦 DM8 + openGauss:RuoYi Office 的 MySQL 数据转换与导入实践

达梦 DM8 + openGauss:RuoYi Office 的 MySQL 数据转换与导入实践

🌐 文档地址 :https://ruoyioffice.com

👇 文章底部获取源码和演示地址 👇

💬 :17156169080(获取产品咨询)
企业管理系统迁入国产数据库,迁移对象除了表结构,还有组织权限、业务主键、流程定义和二进制资源。本文以 RuoYi Office 的包装转换流水线为例,讲清怎样把 MySQL 基线变成可审核、可导入、可验证的达梦与 openGauss 数据包。

▲ 源数据包经过转换和校验,再分别进入达梦 JDBC 与 openGauss gsql 导入路径;流水线同时保留来源、警告与对象统计。

引言:SQL 转完了,为什么流程却发不起来?

SQL 转换成功,首先说明工具产出了目标文本。它并不自动证明所有表都存在、所有数据都保留、运

行时查询都兼容。

企业管理平台尤其依赖"结构 + 初始化资料 + 配置 + 流程资源"的配套。用户记录导入了,但菜单

缺失,登录后仍可能无入口;模型导入了,但部署记录丢失,仍然没有可发起定义。

还有一种更隐蔽的失配:历史 ID 全部导入成功,序列却从较小值开始,第一次新增就出现冲突。

表面现象 真正可能缺失的资产 应验证的产品动作
表结构完整 角色、菜单、字典 登录并打开业务入口
模型列表有内容 部署与流程定义 检查可发起流程
流程图能显示 可写主键与运行表 新增或发布
历史数据能查询 主键序列校准 插入新记录
SQL 执行无报错 长文本或二进制完整性 解析流程资源

因此迁移工作要以"数据包能解释,产品路径能验证"为目标,而非只把语法换成另一种数据库能接受

的形式。

一、从迁移后的产品入口反推数据责任

1. 登录与工作台依赖基础资料

▲ 既有开发环境真实工作台,用于说明初始化资料的产品影响;图中数据库不是本文目标库实测证据。

用户、组织、角色、菜单和字典属于产品运行所需资产。哪些数据放入初始化包,应由产品和交付规

则明确,不能在转换器里临时猜测"这张表大概不重要"。

某些业务表包含演示数据,是否迁移也需要区分初始化交付与客户历史数据迁移。本文采用的历史实

验基线,不等于任何客户生产数据库的全量备份。

2. 可发起流程依赖发布资产

▲ 本地真实流程入口,帮助核对数据迁移后应该出现的能力;入口展示需要结合目标库定义与权限检查。

模型、发布批次、可执行定义和资源内容需要保持配套。只统计设计模型,会遗漏运行资产的完整性

。

3. 业务详情检查字段与关联

▲ 本地开发环境真实单据,展示中文、时间、印章资料与审批身份。它是页面检查示例,不冒充迁移后的目标库单据。

迁移验收应让结构核对与产品行为互相支持。SQL 能看到中文,不代表日期 JSON 契约正确;单据能

打开,不代表新 ID 可以生成。

二、统一入口为什么比直接运行转换器更可靠

RuoYi Office 保留基础转换器原样,通过包装层处理项目已发现的问题。入口位于数据库仓库,实

际转换实现位于交付工程。

这样既能复用基础转换能力,也能把项目补充规则、审核记录和失败门禁保留下来。

1. 明确三个输入和一组版本关系

核心输入是 MySQL schema、static_data 和基础转换器;还需要目标库专用 Quartz 脚本等配套资

产。

输入或资产 责任 缺失的后果
schema 源表结构与类型 字段语义无法恢复
static_data 资料、配置与流程数据 空库不能支撑产品入口
转换器 基础目标语法转换 目标文本无法生成
包装规则 项目特定补充处理 已知问题重复发生
专用 Quartz SQL 任务持久化表 应用调度组件启动失败
运行时应用版本 实际读取与写入契约 数据库基线落后于代码

历史实验使用 2026 年 8 月 31 日的 schema 与 static_data,覆盖 782 张源表。后续应用新增字

段,需要配套目标库增量,不能仅修改应用版本号。

2. 入口先检查路径,再生成并验证清单

以下是现有 PowerShell 入口的核心摘录。它把输入显式传入生成器,再执行 manifest 检查;两个

阶段出现非零退出码都会终止。

powershell 复制代码
foreach ($Path in @($Schema, $Data, $Converter, $UpstreamSql, $Generator, $Adapter)) {
    if (-not (Test-Path -LiteralPath $Path)) { throw "Required path not found: $Path" }
}

& $Python $Generator `
    --schema $Schema `
    --data $Data `
    --converter $Converter `
    --adapter $Adapter `
    --upstream-sql $UpstreamSql `
    --output $Output `
    --python $Python `
    --targets $Targets
if ($LASTEXITCODE -ne 0) { throw "信创 SQL generation failed with exit code $LASTEXITCODE" }

& $Python (Join-Path $PSScriptRoot 'verify_manifest.py') (Join-Path $Output 'manifest.json')
if ($LASTEXITCODE -ne 0) { throw "manifest verification failed with exit code $LASTEXITCODE" }

命令参数使每次转换可以指向明确基线,不依赖"latest 目录里现在恰好是什么"。目标数据库列表

也记录在生成资产中。

现场复用时,应采用自己的固定路径和输出目录,保留原基线与转换结果。本文不执行任何数据库导

入或覆盖客户数据。

三、转换器做语法处理,包装层保留业务语义

1. 先把完整 INSERT 交给转换器

MySQL Dump 可能把一个 INSERT 的字段与多行 VALUES 分开放置。转换器若按物理行解析,容易漏

数据或误读字段。

包装层首先识别完整语句,再合并为可解析形式,同时支持带字段列表的 INSERT。判断完整语句时

需要考虑字符串与转义,不能把任意行尾分号都理解为整条语句结束。

但合并成功并不解决目标导入工具的长度约束。语句解析和目标执行是两项独立责任。

2. 清理规则必须只作用于目标语法

历史问题中,宽泛的 ENGINE.* 清理规则把 Flowable 数据中的 ENGINE_VERSION_ 一并截断,

导致部署与定义数据静默丢失。

当前规则限定到建表选项行。下面摘取相关处理,说明修复发生在输入清理层,不是在运行时查询中

补造部署数据。

python 复制代码
# Only rewrite CREATE TABLE option lines. The upstream ENGINE.* patterns
# also matched Flowable's ENGINE_VERSION_ INSERT column and truncated
# ACT_RE_DEPLOYMENT / ACT_RE_PROCDEF data silently.
content = re.sub(
    r"(?im)^(\)\s*)ENGINE[^;\r\n]*COMMENT", r"\1COMMENT", content
)
content = re.sub(
    r"(?im)^(\)\s*)ENGINE[^;\r\n]*;", r"\1;", content
)
# Upstream splits CREATE TABLE on the first ';'. Keep comment text
# from truncating Jimu / similar tables.
content = re.sub(
    r"COMMENT\s+'([^']*)'",
    lambda match: "COMMENT '" + match.group(1).replace(";", ";") + "'",
    content,
)

这条原则可以推广到其他迁移:文本替换必须知道自己在处理 DDL 选项、字段、字符串还是业务数

据,不能靠相同前缀推断含义。

3. 类型映射不能丢掉原始语义

BIT(1)、长文本、时间、二进制和字符串主键,都需要关注源语义。看到 id 列,不代表它一定

是整数自增;看到 0 / 1,不代表该字段一定应该转为目标布尔类型。

PostgreSQL 对照适配中,普通位值先采用整数导入,Flowable 的指定标志列再转换为引擎要求的 b

oolean。这个结果说明,应区分业务字段与引擎字段,不能一刀切。

转换对象 当前处理方向 仍需核对
整数主键 达梦 IDENTITY / PG 类序列 新 ID 不与历史值冲突
文本主键 保留文本身份 长度、唯一性与大小写
中文字段 保留字符语义 编码、长度与排序
BIT 字面量 归一化再按目标要求处理 是否应为整数或布尔
BLOB / bytea 目标表达式或绑定参数 内容长度与解析结果
日期时间 目标类型与应用契约配对 精度、空值、序列化

金额精度与比较规则也属于数据语义

金额字段应核对精度和小数位,不能只看到目标列仍是 DECIMAL 就结束检查。

对于字符串,还应关注大小写、空格与比较规则对查询和唯一约束的影响。

目标库接受一条记录,不等于它与其他记录之间的业务关系保持不变。

这些检查应使用代表值和实际业务规则,不通过批量清洗历史数据来掩盖差异。

4. 遗漏表兜底需要带着限制交付

基础转换器不能直接处理的六张 ERP 表,包装层提供了有限兜底。兜底解决"产物没有这张表",不

代表该表所有普通索引、复杂默认值和注释已与源库完全一致。

因此兜底表必须进入审核清单。实施人员应检查表结构、主键、唯一约束、普通索引和默认值,再通

过目标模块的实际写入验证。

对业务影响大的表,索引差异即使不影响小数据量功能,也可能影响后续查询性能。功能验收和容量

验证需要分别安排。

四、让流程资源丢失在转换阶段就失败

1. 检查源中存在的关键 INSERT

当前生成器核对四类 Flowable 仓库表:模型、部署、定义和二进制资源。如果源数据有 INSERT、

目标产物却没有,会抛出异常。

python 复制代码
def validate_flowable_repository_data(source_data: str, converted: str, db_type: str) -> None:
    required = {
        "act_ge_bytearray",
        "act_re_deployment",
        "act_re_model",
        "act_re_procdef",
    }
    source_tables = insert_tables(source_data)
    target_tables = insert_tables(converted)
    missing = sorted((required & source_tables) - target_tables)
    if missing:
        raise RuntimeError(
            f"{db_type} conversion lost Flowable repository INSERT data: "
            + ", ".join(missing)
        )

这个门禁判断的是"表级 INSERT 是否保留",并非逐行哈希一致,也没有证明每个资源都可解析。后

续实库检查仍需继续。

把门禁能力说清楚,比把它称作"全量数据一致性校验"更准确。

2. 为产物建立可追溯关系

▲ 迁移交付的逻辑模型,表达源基线、规则版本、目标包与验收记录的关系;这些对象并非平台已新增的数据库业务表。

记录字段 当前用途 不能替代的检查
源文件 SHA-256 固定输入身份 源数据本身正确性
转换器 SHA-256 固定工具来源 规则对业务的适用性
目标 SHA-256 固定产物内容 目标库导入成功
warning 与兜底表 提示人工审核范围 结构与功能回归
对象统计 发现遗漏或计数变化 行数和内容逐项比对
known_limitations 保存交付边界 客户实际验收

当前 manifest 记录基础转换器身份和额外处理规则。进一步提高复建能力时,建议同时归档包装层

源码版本或校验值;不能把现有记录描述成已自动计算每一份代码的哈希。

五、达梦与 openGauss 使用不同导入路径

1. 达梦用 JDBC 承载长语句与二进制

达梦权威导入采用官方 JDBC 逐条执行。二进制表达式会被解析成字节数组,转换为绑定参数后调用

setBytes。

这样可以避免把命令行物理行长度限制带入流程资源导入。导入器还区分函数定义与普通语句的结束

方式。

不过当前实现存在分批提交,已经提交的前序批次不会因后面的异常自动消失。失败后必须检查库状

态,不应假设全量导入具有一个原子事务。

2. openGauss 用 gsql 严格处理执行错误

openGauss 采用 gsql --set ON_ERROR_STOP=on,以避免发生错误后继续执行后续语句。这里的"

严格"指错误终止,不代表所有 DDL 与数据自动整体回滚。

导入后核对 schema、表、中文、流程定义和序列,再启动匹配 Profile。不要反过来依赖应用自动

建表补齐初始化缺失。

导入阶段 达梦 openGauss
运行时 官方 DM JDBC gsql
二进制 字节绑定与目标表达式 bytea / decode 路径
历史整数 ID IDENTITY_INSERT 显式 ID + 序列校准
错误处理 异常终止并保留位置 ON_ERROR_STOP
产品验证 用印审批闭环已有证据 登录、发布、填报已有证据

3. 按时序完成数据到产品的交付

▲ 转换门禁、目标导入与产品验收是三个依次衔接的阶段;前一阶段通过,不替代后一阶段。

六、实库验证为什么不能只比较表数

782 与 783 的差异,在本实验中来自兼容表 dual,不是自动表示缺表或多迁移了一份业务数据。

反过来,即使表数一致,也可能缺索引、默认值或某个流程定义的数据。应按对象类别和代表业务分

层验证。

检查层 示例 通过条件
结构 业务表、Quartz 表、字段类型 与目标包设计一致
资料 用户、字典、印章中文 指定基线完整
引擎资产 模型、部署、定义、资源 关联存在且可用
新数据 取号、保存、发布 主键策略正确
应用读写 登录、表单、流程任务 实际业务语义保持
异常路径 拒绝、启动失败、恢复 状态和恢复方法明确

建议将这些结果写成可复用验收清单,并记录使用的目标库版本。后续刷新 MySQL 基线时,可以重

跑同一套检查,而不是重新发明验收步骤。

七、迁移之后怎样持续升级

初始化迁移是起点,客户后续升级还会收到新增字段、索引和业务数据变更。MySQL 增量不能被默认

视为达梦或 openGauss 可直接执行的增量。

应先确定客户当前基线,转换或编写目标方言的配套升级资产,保留已交付脚本不变,并新增纠错与

升级版本。

已有业务数据的客户还需要明确停写窗口、备份、恢复点和变更顺序。本文实验初始化路径不能直接

变成一个覆盖生产数据的迁移指令。

回滚也要回答应用包、schema 与数据是否能够配套恢复。只回退应用文件,无法自动恢复数据库结

构和新增业务事实。

当一份目标包导入失败:怎样判断重建、补偿还是继续

假设达梦导入在某个长资源语句失败,前面已有几批数据提交。

这时不应立即重复运行全部文件,先固定失败位置和目标库状态。

保留失败语句对应的业务对象

记录脚本文件、语句位置、目标表与数据库错误。

再从源资产确认它是普通业务记录、结构定义,还是流程资源。

日志展示语句时,注意其中可能带业务信息或敏感内容;交付报告保留可定位身份即可。

若是流程二进制,继续检查字节长度、源表达式与目标绑定方式。

若是普通文本,检查编码、长度语义和转义,不先修改通用数据库驱动。

先确认已提交范围

分批提交意味着错误发生前的部分数据可能已经落库。

检查目标表与导入计数,再决定是否在干净测试库重新生成和导入。

不能把事务异常理解成所有 DDL 与历史批次都已回滚。

如果选择继续导入,必须明确语句幂等性和已经执行的结构,不盲目跳过所有重复键错误。

当前达梦导入器只对已确认等价索引的特定情况容错,不是一个"任何报错都跳过"的工具。

回查源资产,不在目标库里临时捂数据

错误类型应回到源 DDL 与转换规则核对。

流程资源缺失应回到清理和 INSERT 解析层。

序列不匹配应回到导入后的校准步骤。

若只在目标库手工补一份数据,下次重新生成仍会重复发生,交付资产也无法解释现场状态。

明确根因后,生成新版本产物并保留旧版本身份,才具备复建能力。

失败类型 推荐处理 需要留下的证据
类型无法转换 对照源 DDL 修正规则 类型语义与新产物身份
定义 INSERT 缺失 限定清理范围与资源门禁 源 / 目标关键 INSERT
二进制执行失败 核对长度与绑定 资源身份和内容验证
主键冲突 核对显式 ID 与序列 MAX、序列与实际取号
普通索引缺失 核对目标结构与查询 索引比对与业务用例
应用字段缺失 配套目标库增量 应用与数据基线关系

不同批次的 manifest 不能互相冒名

统一入口支持多个目标,但某次运行可能只生成一个目标。

例如后续清单记录 targets=postgres,只能作为这次 PostgreSQL 产物的审计依据,不能证明此

前达梦与 openGauss 产物同样来自这个基线。

实验室最初的 782 张源表,和后续基线的对象统计也可能发生变化。

所以客户收到每个目标包时,都应找到它自己的源身份、目标身份和生成记录。

"仓库里有三套 SQL"与"三套 SQL 属于同一批输入"不是一个结论。

警告应当怎样关闭

将警告按表和语义分类,再决定由规则处理还是人工审核。

复杂默认值与普通索引可以逐项核对;无法恢复的业务语义应保留未解决状态。

不能通过删除 warning 文件,让交付清单变成零警告。

关闭一项警告至少应说明原问题、处理方式和新验证结果。

新基线要覆盖哪些回归

刷新初始化资产后,重跑对象核对、登录、发布和代表写入。

再对新增模块或变更字段补测试,不必机械重做所有无关页面。

如果更换了转换器或驱动,则应扩大到对应受影响的语法、认证和写入路径。

变化 回归重点
数据基线刷新 新字段、资料、流程资源
转换器变化 类型、INSERT、结构与门禁
驱动变化 认证、依赖与批量写入
应用升级 运行时 SQL 与业务状态
目标库升级 语法、系统视图与功能行为

让回归范围跟随实际变化,能同时提高效率和证据质量。

清单验证还要与实际文件核对

当前 verify_manifest.py 检查版本、必备处理记录、目标哈希字段、警告引用与兜底记录等。

它不是一套会自动重算所有文件内容、并证明目标库数据一致的审计系统。

实施人员应理解检查器的实际能力,而不是只把 manifest OK 写进报告。

尤其在 SQL 被拷贝、修改或重新压缩后,需要核对最终交付文件与清单身份。

检查 当前用途 交付补充
哈希字段存在 清单记录完整 对实际文件重算与比对
警告有引用 人工审核可定位 阅读并关闭对应问题
关键 INSERT 记录 避免表级资源静默丢失 检查行数与内容可解析
目标列表 确认本次生成范围 分别关联每个交付包

清单、文件和实库结果是三类相互支持的证据。

清单证明来源声明,文件核对证明收到的内容,实库验证证明内容能够被应用使用。

这三项对应完成后,才适合把迁移结果交给下一位实施人员复用。

八、快速体验

在线演示:https://ruoyioffice.com/web/

使用 admin / admin123 查看工作台、发起入口和用印详情,理解迁移资产最终支撑什么产品能力

。

实际转换入口是数据库仓库 tools/xinchuang/generate.ps1。调用时显式传入 schema、static_d

ata、基础转换器、专用 SQL 路径和输出目录;先生成与审核,再导入获准的目标环境。

常见问题(FAQ)

SQL 转换成功,是否可以直接上线?

还需审核产物、实库导入、对象核对和应用回归。当前工具已有完整性门禁,但不代替运行时 SQL

与业务验证。

达梦为什么优先采用 JDBC 导入?

流程资源包含长文本和二进制。现有 JDBC 导入器能按完整语句执行,并对二进制使用绑定参数,避

免命令行长度成为隐含限制。

表数不同一定表示转换错误吗?

需要分析对象类别。实验中 PG 类目标多出的 dual 是兼容表;表数相同也不能独立证明字段、约束

和内容完全一致。

PostgreSQL 转换结果能直接证明人大金仓通过吗?

不能。它是兼容对照资产,人大金仓还需要指定版本、驱动、兼容模式与代表业务的实库验证。

结语:把迁移做成可以审查的流水线

国产数据库迁移的难点,是让源数据、转换规则、目标对象和应用行为一直保持同一种业务语义。

RuoYi Office 的包装层把已发现的问题固化为处理与门禁,把警告、来源和限制留在交付资产中。

实施人员因此能解释每一步做了什么,也能明确还要验证什么。

你们的迁移交付包里,除了目标 SQL,是否还包含源基线、工具身份、警告和代表业务验收记录?这

些资产决定了下一次升级能否顺利复用。

系列阅读

  • openEuler + 毕昇 JDK + Tengine:RuoYi Office 国产化部署实战
  • SpringBoot3 + 达梦 DM8:RuoYi Office 用印申请与多级审批实战
  • SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战
  • 达梦 DM8、openGauss、人大金仓怎么选?RuoYi Office 国产数据库适配与验收指南
  • openEuler + 达梦 DM8 + openGauss:RuoYi Office 多库部署与运行维护实践

如果这篇对你有用,点个「在看」或收藏。

🌐 演示地址 :https://ruoyioffice.com/web

📦 GitHub 源码 :https://github.com/yuqing2026/ruoyi-office

📦 Gitee 源码 :https://gitee.com/yqzy1688/ruoyi-office

💬 微信:17156169080(获取产品咨询)

打开演示地址直接查看系统。

相关推荐
用户0332126663671 小时前
轻松使用 Python 将 RTF 转换为 Word 文档(含批量转换与格式互转)
python
喵了几个咪1 小时前
GoWind ShortPlay 拆解:Ent privacy/viewer 多租户隔离——从中间件到 SQL 的零信任链
sql·中间件·信任链
代码不停1 小时前
MyBatis操作数据库
数据库·mybatis
程序猿乐锅1 小时前
面向对象练习:图书借阅系统里的封装、抽象类与多态
开发语言·前端·数据库·后端·python·学习·1024程序员节
xyouyuweizhu1 小时前
Java IO 流详解:流的作用、流的划分与标准输入输出流
java·python·php
严同学正在努力1 小时前
PostgreSQL 高可用教程(流复制 + Patroni 生产级实战)
运维·数据库·ai·postgresql·架构
牧瀬クリスだ1 小时前
Redis String深度解析:从底层到五大实战场景
数据库·redis·缓存
lumengabc1 小时前
视频制作文字转语音PPT台词生成合成合并视频导出ffmpeg软件python edge-tts
python
她的男孩1 小时前
Spring Boot 表单挂 Flowable 审批:设计器绑模型后,业务侧用注解把单子跑起来
spring boot·低代码·工作流引擎