问题:后台「产品中心 - 产品列表/详情/物模型」报
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,物模型属性正常返回。
42 lines
2.5 KiB
SQL
42 lines
2.5 KiB
SQL
-- =====================================================================
|
||
-- 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;
|
||
|