# V5 数据库迁移修复指南

**问题：** 执行V5迁移脚本时出现 `#1060 - Duplicate column name 'provider_type'` 错误

**原因：** 
1. `provider_type` 列已经存在（之前执行过V5的ALTER TABLE部分）
2. V5中插入的RunningHub模型的 `provider_type` 值为空字符串 `''`，应该是 `'runninghub'`

---

## 📋 解决方案

### 方案1：修复现有数据库（推荐）

如果你已经执行过V5脚本的ALTER TABLE部分，只需要更新数据：

```bash
# 1. 执行修复脚本
mysql -u root -p 1818ai < FIX_V5_provider_type.sql
```

**修复脚本内容：**
```sql
-- 更新所有RunningHub模型的provider_type
UPDATE `points_config` 
SET `provider_type` = 'runninghub' 
WHERE `model_name` LIKE 'rh_sora2_%' 
  AND (`provider_type` = '' OR `provider_type` IS NULL);

-- 验证更新结果
SELECT model_name, provider_type, description 
FROM `points_config` 
WHERE `model_name` LIKE 'rh_sora2_%';
```

**验证步骤：**
```sql
-- 1. 检查列是否存在
SHOW COLUMNS FROM `points_config` LIKE 'provider_type';
SHOW COLUMNS FROM `ai_task` LIKE 'provider_type';

-- 2. 检查RunningHub模型配置
SELECT model_name, provider_type, points_cost, description 
FROM `points_config` 
WHERE `model_name` LIKE 'rh_sora2_%';

-- 预期结果：12个模型，provider_type都是'runninghub'
```

---

### 方案2：从头执行（全新数据库）

如果是全新的数据库或需要重新迁移，使用修正版脚本：

```bash
# 使用修正版脚本
mysql -u root -p 1818ai < V5__add_provider_support_CORRECTED.sql
```

**修正版特点：**
- ✅ 使用 `ADD COLUMN IF NOT EXISTS` 避免重复列错误
- ✅ 使用 `CREATE INDEX IF NOT EXISTS` 避免重复索引错误
- ✅ `provider_type` 值正确设置为 `'runninghub'`
- ✅ ON DUPLICATE KEY UPDATE 包含所有必要字段

---

## 🔍 问题诊断

### 检查当前数据库状态

```sql
-- 1. 检查points_config表结构
DESC `points_config`;

-- 2. 检查是否有provider_type列
SELECT COUNT(*) as has_column
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '1818ai'
  AND TABLE_NAME = 'points_config'
  AND COLUMN_NAME = 'provider_type';
-- 结果为1表示列已存在，0表示不存在

-- 3. 检查现有RunningHub模型的provider_type值
SELECT 
    model_name, 
    provider_type,
    CASE 
        WHEN provider_type = '' THEN '空字符串（错误）'
        WHEN provider_type = 'runninghub' THEN '正确'
        WHEN provider_type IS NULL THEN 'NULL（错误）'
        ELSE CONCAT('其他值: ', provider_type)
    END as status
FROM `points_config`
WHERE `model_name` LIKE 'rh_sora2_%';

-- 4. 检查是否有RunningHub模型记录
SELECT COUNT(*) as runninghub_model_count
FROM `points_config`
WHERE `model_name` LIKE 'rh_sora2_%';
-- 应该是12个
```

---

## 📝 分步修复流程

### 步骤1：备份数据库

```bash
# 备份整个数据库
mysqldump -u root -p 1818ai > backup_before_v5_fix_$(date +%Y%m%d_%H%M%S).sql

# 只备份points_config表
mysqldump -u root -p 1818ai points_config > backup_points_config_$(date +%Y%m%d_%H%M%S).sql
```

### 步骤2：检查表结构

```sql
-- 检查points_config是否有provider相关列
SHOW COLUMNS FROM `points_config` WHERE Field IN ('provider_type', 'provider_config');

-- 检查ai_task是否有provider相关列
SHOW COLUMNS FROM `ai_task` WHERE Field IN ('provider_type', 'provider_task_id', 'provider_response');
```

**预期结果：**
```
-- points_config应该有：
provider_type    | varchar(50) | NO   |     | openai
provider_config  | text        | YES  |     | NULL

-- ai_task应该有：
provider_type      | varchar(50)  | YES  |     | NULL
provider_task_id   | varchar(100) | YES  |     | NULL
provider_response  | text         | YES  |     | NULL
```

### 步骤3：根据情况执行修复

**情况A：列已存在，但RunningHub模型的provider_type值错误**
```sql
-- 直接执行修复脚本
source FIX_V5_provider_type.sql;
```

**情况B：列不存在**
```sql
-- 执行完整的V5脚本（建议使用修正版）
source V5__add_provider_support_CORRECTED.sql;
```

**情况C：部分列存在**
```sql
-- 1. 手动添加缺失的列
ALTER TABLE `points_config`
ADD COLUMN IF NOT EXISTS `provider_type` VARCHAR(50) NOT NULL DEFAULT 'openai' 
    COMMENT 'AI服务提供商类型' AFTER `is_enabled`,
ADD COLUMN IF NOT EXISTS `provider_config` TEXT NULL 
    COMMENT '服务商特定配置（JSON格式）' AFTER `provider_type`;

ALTER TABLE `ai_task`
ADD COLUMN IF NOT EXISTS `provider_type` VARCHAR(50) NULL 
    COMMENT 'AI服务提供商类型' AFTER `task_type`,
ADD COLUMN IF NOT EXISTS `provider_task_id` VARCHAR(100) NULL 
    COMMENT '服务商返回的任务ID' AFTER `provider_type`,
ADD COLUMN IF NOT EXISTS `provider_response` TEXT NULL 
    COMMENT '服务商原始响应（JSON）' AFTER `provider_task_id`;

-- 2. 执行修复脚本
source FIX_V5_provider_type.sql;
```

### 步骤4：验证修复结果

```sql
-- 1. 检查RunningHub模型数量
SELECT COUNT(*) as count 
FROM `points_config` 
WHERE `model_name` LIKE 'rh_sora2_%';
-- 预期：12

-- 2. 检查provider_type值
SELECT 
    COUNT(*) as total,
    SUM(CASE WHEN provider_type = 'runninghub' THEN 1 ELSE 0 END) as correct,
    SUM(CASE WHEN provider_type != 'runninghub' THEN 1 ELSE 0 END) as incorrect
FROM `points_config`
WHERE `model_name` LIKE 'rh_sora2_%';
-- 预期：total=12, correct=12, incorrect=0

-- 3. 查看所有RunningHub模型
SELECT model_name, provider_type, points_cost, description
FROM `points_config`
WHERE `model_name` LIKE 'rh_sora2_%'
ORDER BY points_cost, model_name;

-- 预期输出：
/*
model_name                  | provider_type | points_cost | description
----------------------------|---------------|-------------|---------------------------
rh_sora2_text_portrait      | runninghub    | 160         | RunningHub Sora2 文生视频-竖屏（10秒）
rh_sora2_text_landscape     | runninghub    | 160         | RunningHub Sora2 文生视频-横屏（10秒）
rh_sora2_img_portrait       | runninghub    | 180         | RunningHub Sora2 图生视频-竖屏（10秒）
rh_sora2_img_landscape      | runninghub    | 180         | RunningHub Sora2 图生视频-横屏（10秒）
...（共12条）
*/

-- 4. 检查provider_config是否为有效JSON
SELECT 
    model_name,
    provider_config,
    CASE 
        WHEN JSON_VALID(provider_config) THEN '有效JSON'
        ELSE '无效JSON'
    END as json_status
FROM `points_config`
WHERE `model_name` LIKE 'rh_sora2_%';
-- 所有记录的json_status应该是'有效JSON'
```

---

## ⚠️ 常见错误处理

### 错误1：Duplicate column name 'provider_type'

**错误信息：**
```
#1060 - Duplicate column name 'provider_type'
```

**原因：** 列已经存在

**解决：**
```sql
-- 跳过ALTER TABLE，直接执行修复脚本
source FIX_V5_provider_type.sql;
```

---

### 错误2：Duplicate entry for key 'PRIMARY'

**错误信息：**
```
#1062 - Duplicate entry 'rh_sora2_text_portrait' for key 'PRIMARY'
```

**原因：** RunningHub模型已经插入过

**解决：**
```sql
-- 使用UPDATE而非INSERT
UPDATE `points_config` 
SET 
    provider_type = 'runninghub',
    provider_config = '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait","duration":10}',
    update_time = NOW()
WHERE model_name = 'rh_sora2_text_portrait';

-- 或者直接执行修复脚本（批量更新）
source FIX_V5_provider_type.sql;
```

---

### 错误3：provider_type值为空字符串

**症状：**
```sql
SELECT model_name, provider_type 
FROM `points_config` 
WHERE `model_name` LIKE 'rh_sora2_%';

-- 结果：provider_type显示为空或''
```

**解决：**
```sql
-- 执行修复脚本
source FIX_V5_provider_type.sql;
```

---

## ✅ 验证清单

修复完成后，确认以下所有项：

- [ ] `points_config` 表有 `provider_type` 和 `provider_config` 列
- [ ] `ai_task` 表有 `provider_type`、`provider_task_id`、`provider_response` 列
- [ ] 有12个RunningHub模型记录
- [ ] 所有RunningHub模型的 `provider_type` 值为 `'runninghub'`
- [ ] 所有RunningHub模型的 `provider_config` 是有效的JSON
- [ ] 索引 `idx_provider_task_id` 和 `idx_provider_type_status` 存在

**验证命令：**
```bash
# 执行完整验证
mysql -u root -p 1818ai << 'EOF'
-- 1. 检查列
SELECT 'points_config columns' as check_item, COUNT(*) as result 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '1818ai' AND TABLE_NAME = 'points_config'
  AND COLUMN_NAME IN ('provider_type', 'provider_config');
-- 预期：2

SELECT 'ai_task columns' as check_item, COUNT(*) as result 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '1818ai' AND TABLE_NAME = 'ai_task'
  AND COLUMN_NAME IN ('provider_type', 'provider_task_id', 'provider_response');
-- 预期：3

-- 2. 检查RunningHub模型
SELECT 'RunningHub models' as check_item, COUNT(*) as result 
FROM `points_config` 
WHERE `model_name` LIKE 'rh_sora2_%';
-- 预期：12

-- 3. 检查provider_type正确性
SELECT 'Correct provider_type' as check_item, COUNT(*) as result 
FROM `points_config` 
WHERE `model_name` LIKE 'rh_sora2_%' AND `provider_type` = 'runninghub';
-- 预期：12

-- 4. 检查索引
SELECT 'Indexes' as check_item, COUNT(*) as result 
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = '1818ai' AND TABLE_NAME = 'ai_task'
  AND INDEX_NAME IN ('idx_provider_task_id', 'idx_provider_type_status');
-- 预期：2（至少）

EOF
```

---

## 📞 技术支持

如果遇到其他问题，请提供以下信息：

```sql
-- 1. 数据库版本
SELECT VERSION();

-- 2. 表结构
SHOW CREATE TABLE `points_config`;
SHOW CREATE TABLE `ai_task`;

-- 3. 现有数据
SELECT model_name, provider_type, provider_config 
FROM `points_config` 
WHERE `model_name` LIKE 'rh_sora2_%' OR model_name LIKE 'sora_%';

-- 4. 错误信息截图
```

---

**修复完成！** ✅

执行完修复脚本后，系统应该可以正常使用RunningHub功能了。


