You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4.3 KiB

数据迁移脚本

老结构(厂家/出货单/授权码)→ 新结构(品牌商/生产批次/带 batchno 的授权码)的一次性迁移。 只对应用主库(starpivot)执行,按文件名日期顺序跑。两个脚本都用事务包裹、幂等可重复执行。

执行顺序

# 0) 先备份(必做)
docker exec postgres pg_dump -U starpivot -d starpivot --no-owner --no-privileges -f /tmp/pre.sql
docker cp postgres:/tmp/pre.sql ./starpivot-premigrate-$(date +%Y%m%d-%H%M).sql

# 1) 主迁移
docker cp 2026-07-31-factory-to-brand-batch.sql postgres:/tmp/m1.sql
docker exec postgres psql -U starpivot -d starpivot -v ON_ERROR_STOP=1 -f /tmp/m1.sql

# 2) 补 product.serialcursor(新代码 allocSerialRange 依赖,缺了生产授权码直接报错)
docker cp 2026-07-31-product-serialcursor.sql postgres:/tmp/m2.sql
docker exec postgres psql -U starpivot -d starpivot -v ON_ERROR_STOP=1 -f /tmp/m2.sql

# 3) 方案商改手工 ID + 厂商分组,并按 factoryflag 回填品牌商归属
docker cp 2026-07-31-solution-provider-vendor.sql postgres:/tmp/m3.sql
docker exec postgres psql -U starpivot -d starpivot -v ON_ERROR_STOP=1 -f /tmp/m3.sql

想先看结果不落库:把脚本末尾的 COMMIT; 改成 ROLLBACK; 跑一遍即可。

映射关系

老 新 说明
factory brand id 沿用,所以各表 factoryid 的值无需转换
factory.factoryflag brand.providerid 它就是方案商 ID(十六进制:ABEF/ABF0~ABF4/AB21),解析成整数即可
factory.probatch — 老批次计数器,新结构无对应字段,丢弃
factory_deliverynote production_batch 并上授权码里实际存在的批次(见下)
license_b*.factoryid .brandid 新增列回填,老列保留作对照
license_b*.probatch .batchno 6 位短码,字符集同 comm.GeneratePublicCode
product.factoryid .brandid 改列名
factory_public_code.factoryid .brandid 改列名
— solution_provider 按 factoryflag 的实际取值建 7 条,带 vendor 厂商分组(1=杰里 2=蓝汛 3=恒玄)
老主表 license — 不动。新代码只读分表 license_<pid十六进制>

批次来源取并集:以各 license_b* 分表按 (productid, probatch) 聚合为主(保证每个授权码都挂得上批次), 出货单里有、授权码里没有的补进来;MAC 区间和生产时间用出货单回填。 production_batch.remark 里写了 probatch=<老批次号>,既是对账依据,也是脚本重跑时的幂等锚点。

已知的语义差异

老数据的 number 是批次内序号(每批都从 1 重新计数),而新代码的 number 是产品级全局序号, 由 product.serialcursor 累加分配。因此:

  • 迁移后同一产品的多个批次,serialstart/serialend 会重叠(如都是 1~2),这是老数据本身的性质,无法反推出全局序号;
  • 脚本 2 把 serialcursor 初始化为该产品现有 max(number),新生产的批次序号会接在老数据之后,不会与历史重叠;
  • 授权码 code 由 license.GenerateV2 生成,内部带随机种子,不依赖 serial 唯一,所以老数据 number 重复不会造成主键冲突。

方案商 ID 规则(重要)

solution_provider.id 是手工指定的有含义编码,不自增(列上的序列默认值已 DROP):十六进制看, 0xC101 = 杰里 01 方案、0xC102 = 杰里 02 方案。历史 ID(ABEF/ABF0~ABF4/AB21) 已烧录进设备、不可变更,只能保留;新增方案商一律用 C 开头段。

一个厂商可有多个方案,所以 vendor 分组(enum SolutionVendor)才是「三个方案商」那一层: ABEF→杰里,ABF0~ABF3→蓝汛,ABF4→恒玄,AB21→未指定(慕然科技,待确认)。

因为 id 不自增,api_addsolutionprovider 会强制校验 id 非 0 且不重复——否则不传 id 会插成 0,第二条直接主键冲突。

2026-07-31 广州测试环境的执行结果

品牌商 25、方案商 7、生产批次 64(63 个来自授权码 + 1 个仅出货单登记)、 授权码 37,253 条全部回填 batchno(未填 0、孤儿 0、brandid 与 factoryid 不一致 0)。 25 个品牌商按 factoryflag 全部归属到方案商,未归属 0 个。