fix: 补齐不完整的 v9 商品约束 (#144)
This commit is contained in:
@@ -547,13 +547,16 @@ func MigrateMySQL(db *sql.DB) error {
|
|||||||
return CheckMySQLSchema(db)
|
return CheckMySQLSchema(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
// migrateMySQLV10 修复曾在 v8 开发中间状态记录过版本的数据库。
|
// migrateMySQLV10 修复曾在 v8/v9 开发中间状态记录过版本的数据库。
|
||||||
// v8 迁移本身逐项检查列和索引且回填只处理空值,因此可安全重放;
|
// 两版迁移均逐项检查结构,v8 回填只处理空值,因此可安全重放;
|
||||||
// 历史 v8/v9 版本记录保持不变,完整自检通过后再追加 v10。
|
// 历史 v8/v9 版本记录保持不变,完整自检通过后再追加 v10。
|
||||||
func migrateMySQLV10(db *sql.DB) error {
|
func migrateMySQLV10(db *sql.DB) error {
|
||||||
if err := migrateMySQLV8(db); err != nil {
|
if err := migrateMySQLV8(db); err != nil {
|
||||||
return fmt.Errorf("修复商品目录 SKU v8 结构失败: %w", err)
|
return fmt.Errorf("修复商品目录 SKU v8 结构失败: %w", err)
|
||||||
}
|
}
|
||||||
|
if err := migrateMySQLV9(db); err != nil {
|
||||||
|
return fmt.Errorf("修复蝦皮商品 v9 结构失败: %w", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ func TestMySQLMigrate_V9形状错误不记版本(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMySQLMigrate_已记录V9但缺少SKU来源字段时由V10修复(t *testing.T) {
|
func TestMySQLMigrate_已记录V9但缺少V8V9结构时由V10修复(t *testing.T) {
|
||||||
db := openMySQLMigrationTestDB(t)
|
db := openMySQLMigrationTestDB(t)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
cleanMySQLTestSchema(t, db)
|
cleanMySQLTestSchema(t, db)
|
||||||
@@ -486,6 +486,9 @@ func TestMySQLMigrate_已记录V9但缺少SKU来源字段时由V10修复(t *test
|
|||||||
if err := migrateMySQLV9(db); err != nil {
|
if err := migrateMySQLV9(db); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
// 同时模拟 v9 已记录但两个图片/店铺人工标记约束尚未建立。
|
||||||
|
mustExec(t, db, `ALTER TABLE shopee_products DROP CHECK chk_shopee_products_image_manual`)
|
||||||
|
mustExec(t, db, `ALTER TABLE shopee_products DROP CHECK chk_shopee_products_shop_manual`)
|
||||||
mustExec(t, db, `INSERT INTO schema_migrations(version,applied_at) VALUES
|
mustExec(t, db, `INSERT INTO schema_migrations(version,applied_at) VALUES
|
||||||
(8,'2026-08-11T00:00:00Z'),(9,'2026-08-11T00:00:00Z')`)
|
(8,'2026-08-11T00:00:00Z'),(9,'2026-08-11T00:00:00Z')`)
|
||||||
|
|
||||||
|
|||||||
@@ -445,9 +445,10 @@ MySQL schema v9 为 `shopee_products` 增加 `image_url` 和 `shopee_shop_name`
|
|||||||
商品主图,与 `syb_orders.image_url` 的历史货运单观测图片是两个独立概念。
|
商品主图,与 `syb_orders.image_url` 的历史货运单观测图片是两个独立概念。
|
||||||
|
|
||||||
MySQL schema v10(工单 #144)是兼容修复:部分数据库曾在 v8 开发中间状态提前记录
|
MySQL schema v10(工单 #144)是兼容修复:部分数据库曾在 v8 开发中间状态提前记录
|
||||||
v8/v9,实际缺少 `field_sources` 或 `field_observed_at`。v10 幂等重放 v8 的逐项建列、
|
v8/v9,实际缺少 `field_sources`、`field_observed_at` 或 v9 图片/店铺人工标记约束。
|
||||||
空值回填和唯一索引逻辑,再核对 v8/v9 完整形状;只有全部通过才记录 v10。它不删除
|
v10 幂等重放 v8、v9 的逐项建列、空值回填、约束和唯一索引逻辑,再核对两版完整
|
||||||
或改写旧迁移记录,也不清空商品、SKU 或导入记录。
|
形状;只有全部通过才记录 v10。它不删除或改写旧迁移记录,也不清空商品、SKU 或
|
||||||
|
导入记录。
|
||||||
|
|
||||||
蝦皮详情把 `syb_orders` 按 `(shopee_goods_id, spec_key)` 聚合为“顺运宝观测规格”:
|
蝦皮详情把 `syb_orders` 按 `(shopee_goods_id, spec_key)` 聚合为“顺运宝观测规格”:
|
||||||
订单数按唯一 `syb_id` 行计数,累计数量求和,最近一行提供历史台币售价和图片。
|
订单数按唯一 `syb_id` 行计数,累计数量求和,最近一行提供历史台币售价和图片。
|
||||||
|
|||||||
@@ -93,9 +93,10 @@ HTTP/HTTPS URL,最长 2048 字节;店铺名最长 500 个字符。Admin 只
|
|||||||
迁移只增加列和唯一索引,既有 `sku_id` 继续作为内部主键,因此历史引用不变;若检测
|
迁移只增加列和唯一索引,既有 `sku_id` 继续作为内部主键,因此历史引用不变;若检测
|
||||||
到同商品重复 `spec_key`,迁移会停止且不记录 v8,必须人工确认,不能自动合并。
|
到同商品重复 `spec_key`,迁移会停止且不记录 v8,必须人工确认,不能自动合并。
|
||||||
|
|
||||||
若数据库已经记录 v8 或 v9,但缺少 `field_sources`、`field_observed_at` 等后加入的
|
若数据库已经记录 v8 或 v9,但缺少 `field_sources`、`field_observed_at` 等 v8 结构,
|
||||||
v8 结构,v10 会自动补齐并只回填空值。不要通过删除迁移版本、清库或手工伪造字段来
|
或缺少图片、店铺人工标记约束等 v9 结构,v10 会幂等重放两版迁移并只回填空值。
|
||||||
绕过自检;修复完成且 v8/v9 形状均正确后,程序才会记录 v10。
|
不要通过删除迁移版本、清库或手工伪造结构来绕过自检;修复完成且 v8/v9 形状均
|
||||||
|
正确后,程序才会记录 v10。
|
||||||
|
|
||||||
旧版 Admin 不理解无真实 SKU ID 的新记录。应用回退前应暂停目录接口并确认没有此类
|
旧版 Admin 不理解无真实 SKU ID 的新记录。应用回退前应暂停目录接口并确认没有此类
|
||||||
记录;不要删除 v8 列或把内部主键复制成伪造的外部 SKU ID。
|
记录;不要删除 v8 列或把内部主键复制成伪造的外部 SKU ID。
|
||||||
|
|||||||
Reference in New Issue
Block a user