fix(H): 修复 product_property 驼峰遗留列导致后台产品页面 500

问题:后台「产品中心 - 产品列表/详情/物模型」报
      Unknown column 'completion_mode' in 'field list'(BadSqlGrammarException)

根因:V19(面板 P2 迁移)建列时把 completionMode 直接当作列名写入 product_property(驼峰),
      而 MyBatis-Plus 默认把实体字段 completionMode 映射为下划线形式 completion_mode,
      实体查询/写入时找不到列。
      注:V22 已把 completion_mode 的权威归属判定为 product_action 维度,
      product_property 上的同名列属于历史兼容,保留但统一为下划线命名。

修复:新增 V23 迁移,将 product_property.completionMode 重命名为 completion_mode
  - 幂等可重复执行,三种情形分别处理:
      1) 仅有驼峰列   -> 直接 RENAME COLUMN
      2) 两列都存在   -> 先回填旧列非空值到新列,再 DROP 旧列
      3) 仅有下划线列 -> 跳过
  - 无存储过程、无 DELIMITER(MySQL batch 管道模式下 DELIMITER 失效)
  - 全库扫描(COLUMN_NAME <> LOWER(COLUMN_NAME))确认驼峰遗留列仅此一处

上线过程:全库备份 /opt/iotsaas/backup/iot_platform_before_v23.sql
          -> 克隆库 iot_v23_test 演练两遍(重命名成功 + 幂等无副作用)-> 生产执行 -> 克隆库 DROP

验证:/api/v1/products、/api/v1/products/{id}、/api/v1/products/{id}/spec、
      /api/v1/products/{id}/control-schema 全部返回 200,物模型属性正常返回。
This commit is contained in:
2995840376 2026-10-27 19:12:13 +08:00
parent 56a40edd8e
commit 0ff9103089

View File

@ -0,0 +1,41 @@
-- =====================================================================
-- V23 · 修复历史遗留的驼峰列名(后台产品页面 Unknown column 报错)
-- ---------------------------------------------------------------------
-- 背景:
-- V19(面板 P2 迁移)建列时把 completionMode 直接当作列名写入 product_property,
-- 而 MyBatis-Plus 默认把实体字段 completionMode 映射为下划线形式 completion_mode,
-- 于是实体查询/写入时提示 Unknown column 'completion_mode' in 'field list',
-- 后台「产品中心 - 产品详情 / 物模型」接口 500。
-- 注:V22 已把 completion_mode 的权威归属判定为 product_action 维度,
-- product_property 上的同名列属于历史兼容,保留但统一为下划线命名。
--
-- 处理:把 product_property.completionMode 重命名为 completion_mode
-- 幂等,可重复执行;三种情形分别处理
-- 1) 仅有驼峰列 -> 直接 RENAME
-- 2) 两列都存在 -> 先回填旧列非空值到新列,再删除旧列
-- 3) 仅有下划线列 -> 无需处理
--
-- 无存储过程、无 DELIMITER(MySQL batch 管道模式下 DELIMITER 失效,见 V22 说明)。
-- =====================================================================
SET @has_old = (SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='product_property'
AND BINARY COLUMN_NAME = 'completionMode');
SET @has_new = (SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='product_property'
AND BINARY COLUMN_NAME = 'completion_mode');
-- 情形 1:只有驼峰列 -> 重命名;情形 2:两列都在 -> 回填旧值(旧列随后单独删除)
SET @ddl = (SELECT IF(@has_old = 0,
'SELECT 1',
IF(@has_new = 0,
'ALTER TABLE product_property RENAME COLUMN completionMode TO completion_mode',
'UPDATE product_property SET completion_mode = completionMode WHERE completion_mode IS NULL AND completionMode IS NOT NULL')));
PREPARE st FROM @ddl; EXECUTE st; DEALLOCATE PREPARE st;
-- 情形 2 收尾:删除已回填的驼峰列(情形 1 不触发)
SET @ddl = (SELECT IF(@has_old = 1 AND @has_new = 1,
'ALTER TABLE product_property DROP COLUMN completionMode',
'SELECT 1'));
PREPARE st FROM @ddl; EXECUTE st; DEALLOCATE PREPARE st;