Files
shanxia2.0/docs/data-migration/PRODUCTION_MIGRATION_RUNLOG.md
T
2026-08-03 12:48:52 +08:00

21 KiB
Raw Blame History

生产数据迁移全过程记录(可续写)

用途:记录本次及后续生产环境「三源 → shanxia2.0」数据迁移的全过程,便于续跑、对账、回滚。
权威计划:00-master-plan.md、04-execution-order.md
勿与代码移植文档混淆:docs/crm-migration/、bx-migration/、db-migration/ 管功能移植;本目录管数据灌库。


0. 环境约定(本次)

角色 库名 说明
目标 shanxia2.0 backend/.env.production → DATABASE_URL(主机 121.43.228.102:3306)
CRM + 报销源 sx 同主机;脚本 --source-url .../sx(不要把源 URL 写进 .env.production,Settings 禁额外字段)
地磅源 dibang-test 同主机;--source-url .../dibang-test(不是 dibang)
租户 shanxia2.0 tenant_no 统一
上一次迁移后生产备份 — docs/sql/shanxia2.0-生产-v1.sql(部门等历史门户主数据以此为准抽取)

策略摘要

  1. 业务主键原样保留:id = str(源id)(见 05-id-preservation-policy.md);用户表例外(门户 UUID + user_mapping)。
  2. 逐步清空:每步只 DELETE/TRUNCATE 该步目标表,禁止一次清全库。
  3. 每步:dry-run → 清空当步表 → 正式执行 → 本文件追加日志 + mappings/ / phase-*/logs/。
  4. 迁移脚本:backend/scripts/migrate_*.py(曾在 bede140d 删除,已从 bede140d^ 恢复)。

1. 第一步:部门数据(P0-2)

1.1 权威来源(已确认)

部门数据不要从 sx 迁,而从上一次生产迁移后的备份抽取:

docs/sql/shanxia2.0-生产-v1.sql → 表 sys_dept(共 5 行,remark 多为「数据迁移脚本重建」)。

已抽出可复用产物:

产物 路径
幂等种子 SQL phase-0-foundation/seed_sys_dept_from_prod_v1.sql
映射清单 CSV mappings/dept_from_prod_v1.csv

1.2 v1 备份中的 5 条部门(与 migrate_users.py 硬编码一致)

id parent_id dept_name order_num remark
b13c2be2-4e71-11f1-9f47-00163e3bdd96 0 安庆市山峡化工有限公司 0 数据迁移脚本重建
E65CAAE057914CCCAE2A81BE627A43EA 根 销售部 10 数据迁移脚本重建
F65CAAE057914CCCAE2A81BE627A43EF 根 财务部门 15 用户迁移前新增
C65CAAE057914CCCAE2A81BE627A43ED 根 人力资源部 20 数据迁移脚本重建
D65CAAE057914CCCAE2A81BE627A43EE 根 生产现场部 30 数据迁移脚本重建(用户默认部门)

补充说明:

  • 不是从 sx.sys_dept ETL(sx 快照只有 2 条且主键为 bigint)。
  • 当前「测试模型」快照 shanxia2.0.sql 通常只有根 + 销售,缺财务/人力/生产现场 → 必须以 生产-v1 补齐,用户 dept_id 才不孤立。

1.3 执行步骤(续跑时勾选)

  • 生产盘点:SELECT id, parent_id, dept_name, order_num, del_flag FROM sys_dept WHERE del_flag=0 ORDER BY order_num;
  • 仅本表 DELETE:本次用幂等 UPSERT,未整表 DELETE(原有 2 行被 UPDATE 名称/排序)
  • 执行 seed_sys_dept_from_prod_v1.sql
  • 验收:5 行齐全,ID 与 migrate_users / roster 一致
  • (可选)补写 phase-0-foundation/step-02-dept.md

1.4 本步执行日志

时间 操作 结果 备注
2026-07-31 从 shanxia2.0-生产-v1.sql 抽取部门 5 行;已生成 seed SQL + CSV
2026-07-31 对生产执行 seed SQL 成功 执行前 2 行(山峡化工/销售部门)→ 执行后 5 行齐全;根改名为「安庆市山峡化工有限公司」,销售部 order_num=10;新增财务/人力/生产现场

2. 全过程阶段清单(对照执行)

P0 基础

步 内容 脚本/方式 状态(本次)
0-1 字典 一般无需批量导入 历史:已验收跳过
0-2 部门 从 shanxia2.0-生产-v1.sql 抽 5 行种子 已完成(2026-07-31 幂等写入生产)
0-3 角色 + 角色菜单 从 shanxia2.0-生产-v1.sql 全量恢复 sys_role/sys_role_menu 已完成(2026-07-31):角色 12 / 菜单关联 452;见 phase-0-foundation/logs/2026-07-31-sys-role.md
0-4 用户 改从 shanxia2.0-生产-v1.sql 恢复 sys_user/sys_user_role/sys_role(+活跃 role_menu) 已完成(2026-07-31):有效用户 26;见 phase-0-foundation/logs/2026-07-31-sys-user.md

P1 CRM(源 sx)

步 脚本 当步清空表 状态(本次)
1-1a migrate_crm_product_category.py crm_product_category 已完成;status 曾误为 1,已修复为 0(正常)
1-1b migrate_crm_product.py crm_product 已完成(2026-07-31):--clear-target 后插入 247(与 sx del_flag=0 一致);id 如 '1' 原样
1-1c renumber_crm_product_no.py --apply 不删表,改编号 已完成(2026-07-31):247 条 → SXWL+6 位;映射 crm_product_no_mapping.csv;下一号 SXWL000248
1-2 migrate_crm_customer.py pool/follow/contact/customer 已完成;2026-07-31 下午再同步:252 / 119 / 1 / 2(较上次 +1/+1)
1-2b migrate_crm_payment_invoice.py crm_invoice_info 已完成(2026-07-31):DELETE 后插入 201;id 恒等;回款/发票主表源库 0 行跳过
1-3a migrate_crm_clue.py clue_follow/clue 已完成(2026-07-31):DELETE 后 clue 1 / follow 0;id='12' 与 sx 恒等
1-3b migrate_crm_opportunity.py opportunity 四表 已完成(2026-07-31):sx 四表均为 0;已清空目标残留(opp 2/follow 5/stage 6);映射 CSV 仅表头
1-4a migrate_crm_quote.py quote 相关 + supplier 已完成;2026-07-31 下午再同步:supplier 2 / quote 986 / product 1347 / approval 916(较上次 +2/+2/+2)
1-4b migrate_crm_contract.py contract 六表 已完成;2026-07-31 下午再同步:contract 962 / product 1338 / approval 440(较上次 +2/+2)
1-5 migrate_crm_sys_oss.py 慎清 sys_oss 已提前完成(2026-07-31):DELETE 291 → 插入 355;id 恒等;biz 回填 87

P2 报销(源 sx)

步 命令 状态
2-1~2-4 migrate_bx_data.py --phase base|advance|reimburse|attachment P2 全部完成(2026-07-31):base / advance / reimburse / attachment

P3 地磅(源 dibang-test)

步 命令 状态
3-1 db_vehicle / 源 vehicles 门户无 db_vehicle → 跳过(源 158 辆不迁)
3-2 migrate_dibang_data.py --truncate-target --include-deleted 已完成(2026-07-31):plan 109 / IO 2359 / slip 1823;映射 dibang_id_mapping.json

对账:源/目标三表 COUNT 一致。--include-deleted 后仅 1 条孤儿警告:weighing#84 引用源库已不存在的 inbound_outbound.id=94(目标 inbound_outbound_id 置空)。日志见 phase-3-dibang/logs/。

P4 验收

  • 源/目标 COUNT 对账、抽样单据、中文名登录、附件 URL — 部分:地磅三表 COUNT 已对账;其余抽样/登录/附件仍待做

3. 操作命令模板(密码脱敏)

cd backend
export PATH="venv/bin:$PATH"
SX_URL='mysql+pymysql://USER:PASS@HOST:3306/sx'
DIBANG_URL='mysql+pymysql://USER:PASS@HOST:3306/dibang-test'

# 用户(示例)
ENV_FILE=.env.production python scripts/migrate_users.py \
  --env-file .env.production --source-url "$SX_URL"

# CRM 分类(示例:先 SQL DELETE 当步表,再执行)
ENV_FILE=.env.production python scripts/migrate_crm_product_category.py \
  --env-file .env.production --source-url "$SX_URL" \
  --user-mapping ../docs/data-migration/mappings/user_mapping_result.csv \
  --mapping-out ../docs/data-migration/mappings/crm_product_category_id_mapping.csv

逐步 DELETE 示例见计划;子表先于父表。


4. 批次时间线(追加写,禁止覆盖历史)

批次 2026-07-31(中断暂停)

时间(约) 动作 结果
当日上午 恢复 backend/scripts/migrate_*.py(自 bede140d^) 完成
连通校验:shanxia2.0 / sx / dibang-test OK;sx 产品 248、客户 259、报价 1002、合同 995;dibang-test 计划 109 / 出入库 2355 / 地磅单 1821
正式 migrate_users.py(sx) 曾新增 25 用户(后被库覆盖/清掉;已作废,不以本次为准)
DELETE + migrate_crm_product_category 插入 5
DELETE + migrate_crm_product 插入 247
renumber_crm_product_no 仅 DRY-RUN
用户要求暂停 客户及以后 / 报销 / 地磅 未写
同日稍后 执行部门 seed SQL 生产 sys_dept 5 行齐全
同日稍后 用户改从生产-v1 恢复 sys_user 26 / 活跃 user_role 9;刷新 user_mapping_result.*(UUID 与上次迁移一致)
同日稍后 角色从生产-v1 全量对齐 sys_role 12(有效 6)+ sys_role_menu 452;映射 role_from_prod_v1.csv
同日稍后 6 个新菜单授权给全部角色 发票夹×2、改选申请人、主体危化品能力×2、三方驾押人员 → 12 角色均 6/6;见 logs/2026-07-31-grant-new-menus.md
同日稍后 角色-菜单关系先按生产-v1 重灌 DELETE 后 INSERT 452;再补授 6 新菜单 +72 → 合计 524;见 logs/2026-07-31-sys-role-menu-v1.md
同日稍后 产品分类 + 产品从 sx 重灌 分类 5(status=1);产品 247;id 与 sx 一致;映射 CSV 已刷新
同日稍后 产品编号统一 SXWL+6 位 247 行全部更新;product_id 不变;见 mappings/crm_product_no_mapping.csv
同日稍后 修复分类 status 误写成 1(停用) → 改回 0(正常);脚本已按若依语义回修
同日稍后 恢复 scripts/migration/minio_url.py 客户证照 OSS ID→URL 依赖
同日稍后 客户四表从 sx 重灌 DELETE 后:customer 251 / contact 118 / follow 1 / pool 2;id 恒等;75 条「未分类」置空;见 logs/2026-07-31-customer-migrate.md
同日稍后 开票信息 crm_invoice_info DELETE 6 → 插入 201;id 恒等;3 条挂已软删客户;见 logs/2026-07-31-invoice-info.md
同日稍后 线索 crm_clue DELETE 残留后:clue 1(id=12 陈福威)/ follow 0;见 logs/2026-07-31-clue.md
同日稍后 商机四表 sx 全空;DELETE 目标残留后插入 0;见 logs/2026-07-31-opportunity.md
同日稍后 附件 sys_oss(提前于报价) DELETE 门户原 291 → 从 sx 插入 355;id 恒等;biz 回填 87 / 未挂业务 268;见 logs/2026-07-31-sys-oss.md
同日稍后 客户证照 URL 回填 41 家客户营业执照/许可证等相对路径已写入;见 mappings/crm_customer_license_url_backfill.csv
同日稍后 报价四表 + 供应商 DELETE 残留后:quote 984 / product 1345 / approval 914 / supplier 2;id 恒等;见 logs/2026-07-31-quote.md
同日稍后 合同六表 DELETE 残留后:contract 960 / product 1336 / approval 440;id 恒等;见 logs/2026-07-31-contract.md
同日稍后 OSS biz 回填(合同) --skip-insert;修好 JSON ossId 解析后回填 189(合同附件);现 biz:customer 87 + contract ~189
同日稍后 合同附件 ossId→相对路径 184 合同 / 188 处替换;门户约定 ossId 存 MinIO key;见 mappings/crm_contract_attachment_url_backfill.csv
同日稍后 报销 P2-1 基础数据 expense_item 48(alive 37)/ workflow_def 2(备用金+报销单)/ node 4;审批人已映射;见 phase-2-bx/logs/2026-07-31-bx-base.md
同日稍后 报销 P2-4 附件 DELETE 41 → 插入 155;file_path 相对路径原样;biz_id 待 advance/reimburse 迁入后对齐;见 phase-2-bx/logs/2026-07-31-bx-attachment.md
同日稍后 报销 P2-2 备用金 apply 13 / approval 27(含发放字段 issue_*);id 恒等;见 phase-2-bx/logs/2026-07-31-bx-advance.md
同日稍后 报销 P2-3 报销单 apply 127 / detail 170 / approval 195 / offset 4;id 恒等;1 条用户字段警告;见 phase-2-bx/logs/2026-07-31-bx-reimburse.md
同日稍后 用户密码重置 25 人恢复为 2026-07-12 user_import_accounts.md 首次 4 位密码(bcrypt);见 phase-0-foundation/logs/2026-07-31-reset-passwords-to-20260712.md
同日稍后 地磅 P3 dry-run 仅存活:plan 99 / IO 2044 / slip 1823,孤儿 FK 警告 40;含软删:109 / 2359 / 1823,孤儿仅 1
同日稍后 地磅 P3 正式迁移 --truncate-target --include-deleted:写入 plan 109 / IO 2359 / slip 1823;COUNT 与源一致;见 phase-3-dibang/logs/2026-07-31-dibang-migrate.md
同日稍后 清空发票夹业务数据 DELETE:invoice 8 / ledger 8 / summary 2 / reimburse_invoice 1 / attachment(invoice) 1;见 phase-2-bx/logs/2026-07-31-clear-invoice-wallet.md
同日下午 客户再同步 DELETE 后:customer 252 / contact 119 / follow 1 / pool 2;证照回填 42;见 logs/2026-07-31-customer-resync-migrate.md
同日下午 合同再同步(中断后续跑) 主表 962 先入;续跑 product 1338 / approval 440;清掉 18 条非源 UUID 审批残留;附件路径无需再替(migrate 已展开);见 logs/2026-07-31-contract-resync-migrate-resume.md
同日下午 报价再同步 DELETE 后:supplier 2 / quote 986 / product 1347 / approval 916;见 logs/2026-07-31-quote-resync-migrate.md
同日下午 清空运输管理测试数据 全部 pl_*(承运商/车辆/人员/计划/出入库/证照等)按租户 DELETE → 0;未动 db_*;见 phase-pl/logs/2026-07-31-clear-pl-test-data.md
2026-08-01 再导入前清空 pl_* 残留 plan/product 各 1 → 全部 pl_*=0;见 phase-pl/logs/2026-08-01-clear-pl-before-reimport.md
2026-08-01 产品分类 + 产品再迁移 --clear-target:分类 5(status=0)/ 产品 248;与 sx 一致;见 logs/2026-08-01-product-*-migrate.md
2026-08-01 附件 sys_oss 再迁移 DELETE 355 → 插入 362;biz 回填 281 / 未挂 81;见 logs/2026-08-01-sys-oss-migrate.md
2026-08-01 客户四表再迁移 DELETE 后:customer 253 / contact 119 / follow 1 / pool 2;证照回填见 logs/2026-08-01-customer-*.md
2026-08-01 开票/线索/商机/报价/合同 invoice_info 203;clue 1;opp 0;quote 989/1352/919;contract 966/1344/688;中断后续跑审批与合同重灌已对齐
2026-08-01 地磅再迁移 源 dibang-test,--truncate-target --include-deleted:plan 118 / IO 2386 / slip 1840;见 phase-3-dibang/logs/2026-08-01-dibang-migrate.md
2026-08-01 报销再迁移 base→advance→reimburse→attachment:item 48 / wf 2+4 / advance 13+27 / reimburse 127+170+195+4 / att 155;见 phase-2-bx/logs/2026-08-01-bx-*-migrate.md
2026-08-02 清空运输业务单据(保留主数据) 清计划/出入库/运费/ETC/维保等;保留承运商10/车辆13/人员22/证件90/提醒5;见 phase-pl/logs/2026-08-02-clear-pl-ops-keep-master.md
2026-08-01 地磅再迁移 dibang-test → --truncate-target --include-deleted:plan 118 / IO 2386 / slip 1840;孤儿 weighing#84→IO94;见 phase-3-dibang/logs/2026-08-01-dibang-migrate.md
2026-08-02 CRM 业务再同步(不含产品) 见下节「批次 2026-08-02」

批次 2026-08-02(CRM 重迁:不含产品分类/产品)

约定:不重迁 crm_product*;sys_oss 仅增量(不 DELETE,保留运输等门户附件)。

时间(约) 动作 结果
当日晚 sys_oss 增量 插入 0 / 更新 362;目标仍 482(sx 362 + 门户约 120);见 phase-1-crm/logs/2026-08-02-sys-oss-incremental.md
当日晚 客户四表 DELETE 后:customer 253 / contact 119 / follow 1 / pool 2;id 与 sx 存活集恒等;77 条「未分类」置空;见 logs/2026-08-02-customer-remigrate.md
当日晚 开票信息 invoice_info 203;见 logs/2026-08-02-invoice-info-remigrate.md
当日晚 客户证照回填 43 家至少一证有 URL;见 logs/2026-08-02-customer-license-backfill.md
当日晚 线索 / 商机 clue 1 / follow 0;opp 四表 0;见 logs/2026-08-02-clue-remigrate.md、opportunity-remigrate.md
当日晚 报价 supplier 2 / quote 989 / product 1352 / approval 919;见 logs/2026-08-02-quote-remigrate.md
当日晚 合同 contract 966 / product 1344 / approval 688;附件回填需更新 0(migrate 已展开路径);见 logs/2026-08-02-contract-*.md
— 产品未动 crm_product 仍为门户侧 367(与 sx 249 不对齐属预期,本批次刻意跳过)

对账(del_flag=0):客户/联系人/开票/线索/报价/合同与 sx 存活 COUNT 及 id 集合一致。

| 当日晚 | 报价/合同审批批量办结 | 报价 submitted→accepted 726;报价审批 pending→approved 824;合同 approving→approved 673;合同审批 pending→approved 682;见 logs/2026-08-02-force-approve-quote-contract.md | | 当日晚 | 报销 P2 全量重迁 | DELETE 业务表后 --phase all:item 48 / wf 2+4 / advance 13+27 / reimburse 127+170+195+4 / att 155;未动发票夹;见 phase-2-bx/logs/2026-08-02-bx-all-remigrate.md | | 当日晚 | 地磅 P3 全量重迁 | 源 dibang-test,--truncate-target --include-deleted:plan 118 / IO 2392 / slip 1852;孤儿 weighing#84→IO94;见 phase-3-dibang/logs/2026-08-02-dibang-migrate.md | | 2026-08-03 | 增量同步 IO#2398 | 出入库 2398(UPDATE)+ 地磅单 1895(INSERT);车皖H38397 / CRKDH0002048 / 净重 34330;见 phase-3-dibang/logs/2026-08-03-sync-io-2398.md | | 2026-08-03 | 同步当日全部单据 | 源 dibang-test 2026-08-03:IO 6(INSERT 2 UPDATE 4)/ slip 2(INSERT 1 UPDATE 1);计划 0;见 phase-3-dibang/logs/2026-08-03-sync-today.md |

续跑建议

  1. P1 CRM / 审批办结 / P2 报销 / P3 地磅 已完成。
  2. P4 验收:抽样列表页、附件 URL、地磅单据。

5. 相关产物路径

类型 路径
用户映射 mappings/user_mapping_result.csv
用户部门花名册 mappings/user_import_roster.csv
初始密码(敏感,勿外传) mappings/user_import_credentials.csv
产品分类/产品映射 mappings/crm_product_category_id_mapping.csv、crm_product_id_mapping.csv
客户映射 mappings/crm_customer_id_mapping.csv(251 行,source_id=new_id)
开票信息映射 mappings/crm_invoice_info_id_mapping.csv(201 行,source_id=new_id)
线索映射 mappings/crm_clue_id_mapping.csv(1 行,source_id=new_id=12)
商机映射 mappings/crm_opportunity_id_mapping.csv(0 数据行;sx 无商机)
附件 OSS 映射 mappings/crm_oss_id_mapping.csv(355 行);biz:crm_oss_biz_backfill.csv;未挂:crm_oss_unresolved.csv
报价映射 mappings/crm_quote_id_mapping.csv(984 行,source_id=new_id)
合同映射 mappings/crm_contract_id_mapping.csv���960 行,source_id=new_id)
地磅映射 mappings/dibang_id_mapping.json(plan 109 / IO 2359 / slip 1823)
阶段日志 phase-0-foundation/logs/、phase-1-crm/logs/、phase-2-bx/logs/、phase-3-dibang/logs/
主键策略 05-id-preservation-policy.md

6. 修订记录

日期 修订
2026-07-31 建档;回答部门历史结论;记录已执行用户/分类/产品与暂停点
2026-07-31 确认部门权威源为 shanxia2.0-生产-v1.sql;抽出 5 行 seed SQL + CSV
2026-07-31 用户改为从 shanxia2.0-生产-v1.sql 恢复(非 sx migrate_users);完成并留痕
2026-07-31 角色/角色菜单按生产-v1 全量对齐;完成并留痕
2026-07-31 新版 6 菜单授予生产全部 12 角色;完成并留痕
2026-07-31 P3 地磅从 dibang-test 正式迁入(含软删);三表 COUNT 对账通过