旧库数据迁移
把旧系统(api_yeomai_site)的数据迁到新库,供新服务端使用。
前置条件
- 新库已建好,
DATABASE_URL指向它,且已执行建表(pnpm prisma:migrate)。 - 旧库 dump 文件位于仓库根目录
数据库/api_yeomai_site_mysql.sql(默认路径;可用环境变量LEGACY_DUMP覆盖)。 STATIC_BASE_URL已配置为新静态资源域名,用于改写内容字段里的旧域名。
三条命令
# 1. 体检:确认旧数据能无损映射(不连数据库,纯读 dump)
pnpm legacy:check
# 2. 试运行:完成全部转换,但不写库,用来核对行数
pnpm legacy:migrate -- --dry-run
# 3. 正式迁移
pnpm legacy:migrate
如希望直连旧库读取而不是读 dump:
pnpm legacy:migrate -- --from-db # 需配置 LEGACY_DATABASE_URL
迁移做了什么
| 旧表 | 新表 | 说明 |
|---|---|---|
| 用户信息 | users |
284 行 |
| 用户已购课程 | entitlements |
48 行,source=2(老数据),不走支付直接标记为已拥有 |
| 课程口令码读取信息 | courses |
10 行,code 原值保留 |
| 视频课程数据 | lessons |
841 行,章节id/播放id 原值保留 |
| 免费视频课程数据 | free_lessons |
12 行 |
| 首页课程列表 | home_courses |
5 行,并自动关联到对应付费课程 |
| 首页免费课程列表 | home_free_courses |
3 行 |
| 首页横幅图片 | banners |
3 行 |
| 网页列表 | articles |
2 行 |
| 课程页面Tips | course_tips |
2 行 |
| cloudconfig | settings |
13 行 → 12 行(ID 0 占位丢弃),数字 ID 改字符串 key |
| 课程口令码 | — | 作废,不迁移 |
各类 xxx2 备份表、网页数据、验证码发送 |
— | 废弃 |
必须知道的四件事
1. 内容字段里的旧域名会被改写
旧库的 首页课程列表.内容(44 处)和 网页列表.网页内容(4 处)里存的是绝对 URL,
形如 https://api.yeomai.site/Images/...。旧域名退役后这些图片/视频会全部 404。
迁移时按 STATIC_BASE_URL 自动改写。执行前务必确认这个变量填的是新静态域名。
2. 时间按 +08:00 换算
旧库时间由服务器本地 NOW() 写入,是北京时间墙钟值。新库统一存 UTC,
迁移时按 +08:00 换算(可用 LEGACY_UTC_OFFSET 覆盖)。
注意旧库中确实存在 2024-02-01 这种只有日期没有时间的值,已单独处理。
3. courses.code 绝对不能被改写
它同时是视频目录名(Course/{code}/…/playlist.m3u8)与封面名(Course/{code}.png)。
迁移脚本对它逐字透传,测试中有断言保护。
4. 迁移会清空新库业务表
脚本采用「先清空再写入」实现幂等,失败可原样重跑。
安全阀:若新库已存在订单数据(说明已上线),脚本会拒绝执行,必须显式加 --force。
迁移后核对
脚本会自动逐表比对行数。此外建议人工抽查:
- 随机选几个老用户,确认其
entitlements里的课程与升级前一致。 - 打开首页,确认轮播、新课长图、试听入口图片都能加载(验证域名改写生效)。
测试
迁移的转换逻辑由 transform.test.ts 覆盖(18 项),跑的是真实的旧库 dump:
pnpm test
其中包含行数比对、唯一性约束、域名改写、时间换算、首页长图与课程的关联完整性。 改动迁移逻辑后请先跑测试。