Page:
Task-92-Sense旧设备能力JSONB兼容迁移
Pages
Architecture-and-Code-Map
Audience-Document-Template
Business-Rules-and-Glossary
Common-Changes
Delivery-Documentation-Guide
Deployment-Template
Deployment-and-Operations
Development-Workflow
Existing-Project-Adoption-Guide
Home
Local-Development-and-Verification
Multi-Agent-Collaboration
New-Project-Documentation-Setup
Product-Requirements
Product-Roadmap
Project-Profile
Requirements-Migration-Matrix
Task-1-三项目并行建单与协同工单顺序
Task-101-Sense-GoAdmin-应用外壳
Task-104-Sense-30天登录有效期
Task-106-Sense-本机-Supervisor-实例
Task-12-Bell独立登录RBAC与认证审计
Task-17-Bell不可变Event与永久幂等收据
Task-18-Bell开发测试合成事件入口
Task-19-Bell规则匹配与Event-Alert链路
Task-20-Bell-Alert并发处置与审计时间线
Task-21-Sense独立GoAdmin产品骨架
Task-22-Sense独立登录RBAC与审计
Task-23-Sense设备台账与凭据边界
Task-24-ONVIF与RTSP视频接入验证
Task-25-MediaMTX进程与状态对账
Task-26-Sense单路实时监看
Task-27-Sense区域与方向警戒线版本配置
Task-28-三项目当前MVP交互原型
Task-3-GoAdmin默认模块精简与UI组件复用
Task-30-Sense原型对齐GoAdmin与Element-Plus
Task-31-Bell原型对齐GoAdmin与Element-Plus
Task-32-Sense网管与非技术人员原型
Task-33-Bell普通用户预警处理原型
Task-36-Bell-MVP文档与待验收归档
Task-37-Sense-Windows前后端一键打包
Task-40-Sense全模式密码最短6位
Task-42-Sense密码策略仅限制最短6位
Task-44-Sense管理员侧栏模块为空修复
Task-46-Sense-Windows包内配置加载
Task-48-支持ONVIF-Digest认证与安全Media地址归一化
Task-5-冻结Sense与Bell-GoAdmin技术基线
Task-50-ONVIF与RTSP分离凭据并持久化Profile
Task-51-接入成功后自动建立媒体路由并进入实时监看
Task-54-修复实时监看按需拉流循环等待
Task-56-修复设备编辑请求包含新建专用字段
Task-58-建立explore-main-dev分支治理并重置GoAdmin开发基线
Task-61-Sense冻结GoAdmin源码产品骨架
Task-64-Sense登录RBAC与审计
Task-65-Sense设备台账与凭据边界
Task-66-Sense视频接入与Profile
Task-67-Sense视频服务生命周期与状态对账
Task-68-Sense单路实时监看与播放状态反馈
Task-69-Sense多边形区域与方向警戒线配置
Task-70-Sense-Windows配置启动与打包交付
Task-9-Bell独立GoAdmin产品骨架
Task-90-Sense项目根目录Windows启动脚本
Task-92-Sense旧设备能力JSONB兼容迁移
Task-95-Sense旧媒体路由唯一约束兼容迁移
Task-97-Sense免验证码登录与管理员密码重置
Task-99-Sense登录页只读配置接口
Task-Archive-Template
Troubleshooting
Clone
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
92 Sense旧设备能力JSONB兼容迁移
- 类型:缺陷
- 所属 Epic:#7
- 所属 MVP / 版本:#8
- 状态:已完成
- 日期:2026-08-15
- Gitea 工单:#92
- Wiki 页面:Task-92-Sense旧设备能力JSONB兼容迁移
- Wiki revision:见本地镜像头
背景与目标
用户通过 Windows 包启动 Sense 时,设备迁移报 PostgreSQL SQLSTATE 42804。只读诊断确认旧数据库的 sense_devices.capabilities 为 text NOT NULL DEFAULT ''::text,一条旧记录保存受支持的单值能力但不是 JSON;新模型要求 JSONB,GORM AutoMigrate 无法直接转换旧默认值和数据。
目标是在不删除设备、不跳过迁移、不修改当前用户数据库的前提下,为旧 schema 提供确定性、可回滚的 JSONB 兼容迁移。
最终方案
在现有 2026081414000 设备迁移事务开头执行 PostgreSQL 专用兼容步骤。受影响数据库尚未登记该迁移版本,后置新版本无法越过失败点,因此兼容逻辑必须放在原失败迁移内。
兼容步骤只处理既有 text/varchar 列:取得 ACCESS EXCLUSIVE 表锁,读取并验证全部旧值后才开始改变默认值和数据。空值转为 [];六种受支持旧单值转为单元素 JSON 数组;合法字符串数组规范化后保持语义。未知单值、对象、非字符串数组、未知数组元素和超过 16 项的数组会返回不含业务值的错误,整个事务回滚。
全部验证通过后删除旧 text 默认值,参数化更新规范 JSON,使用显式 USING capabilities::jsonb 转型并设置 '[]'::jsonb 默认值,再继续原有 GORM AutoMigrate、菜单、权限和迁移版本登记。非 PostgreSQL、表/列不存在以及已是 json/jsonb 时不执行旧值转换。
修改文件
Sense/server/cmd/migrate/migration/version/2026081414000_device.go:事务内旧 text 能力验证、转换、锁表和 JSONB 默认值处理。Sense/server/cmd/migrate/migration/version/2026081414000_device_test.go:纯函数和隔离 PostgreSQL 17 回归,包括完整设备迁移与版本登记。- Wiki
Troubleshooting、docs/06-troubleshooting.md:备份、重试、未知旧值和回退说明。 wiki-docs.json、docs/task/92-Sense旧设备能力JSONB兼容迁移.md:任务归档登记和镜像。
验收结果
| 验收标准 | 结果 |
|---|---|
| 旧 text 默认值不再触发 SQLSTATE 42804 | 通过;隔离 PostgreSQL 重现结构成功转为 jsonb |
| 旧单值无损转换为 JSONB 数组 | 通过;video 转为单元素数组 |
| 空值与合法数组正确处理 | 通过;空字符串转空数组,合法数组保持顺序与值 |
| 未知值拒绝且无半成品 | 通过;类型、默认值和已验证行均保持旧状态 |
| 新库、jsonb 和重复执行兼容 | 通过;无表跳过、jsonb 重复调用无操作 |
| 全量 Go 和迁移回归通过 | 通过 |
| 当前用户数据库未被修改 | 通过;仅执行只读诊断,写测试使用独立数据库并在结束后删除 |
| Wiki 与归档一致 | 受影响页面定向检查通过 |
测试
go test ./cmd/migrate/migration/version -run TestCanonicalLegacyCapabilities -count=1 -v:通过。- 隔离 PostgreSQL 17
TestDeviceCapabilitiesMigrationOnPostgres:旧单值/空值/合法数组、未知值事务回滚、无表、重复调用、完整设备迁移和sys_migration登记全部通过。 - 隔离数据库
sense92_migration_test测试前确认不存在,测试后确认计数为 0。 go test ./...、go vet ./...、go build ./...:通过。go test -race ./cmd/migrate/migration/version -run TestCanonicalLegacyCapabilities -count=1:通过。git diff --check:通过。- 受影响 Wiki 定向同步与检查:通过。
- 未验证部分:按工单安全边界未在当前用户
sense数据库执行写迁移,也未替换当前Sense/dist中的待验收 #70 二进制;需先备份,再部署包含 #92 的新包进行最终启动验收。全量 Wiki 检查仍会先发现待验收 PR #89 的 #70 镜像尚未合入dev。
用户验收
- 用户于 2026-08-15 明确确认
#92 验收通过。 - 实现 PR #93 已合入
dev,合并提交为eaa6ae081542b0b9c74cc2d92a9138639fdbe530。 - #92 已完成;真实数据库备份、交付包重建与启动回归继续在 #70 的交付闭环中执行。
遗留问题
- 当前交付包仍含 #92 修复前的
sense.exe。#92 合入dev后需让 #70 交付分支吸收该提交并重新打包,用户备份数据库后再运行迁移。 - Harness strict 的 #66/#67 既有归档格式问题不属于本工单。
相关提交
68b436a兼容旧设备能力字段迁移。fe3badf覆盖旧设备完整迁移链。aee5f45记录设备能力迁移排错。