fix: 修复迁移日志表数据

This commit is contained in:
tbphp
2025-07-17 20:37:23 +08:00
parent 313d14797f
commit 2c4315d26e

View File

@@ -7,25 +7,25 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// TODO: 更新迁移,待多个版本后旧版本都升级差不多之后移除。
func V1_0_13_FixRequestLogs(db *gorm.DB) error { func V1_0_13_FixRequestLogs(db *gorm.DB) error {
return db.Transaction(func(tx *gorm.DB) error {
// 如果有key_id就执行修复 // 如果有key_id就执行修复
if !tx.Migrator().HasColumn(&models.RequestLog{}, "key_id") { if !db.Migrator().HasColumn(&models.RequestLog{}, "key_id") {
return nil return nil
} }
logrus.Info("Old schema detected. Starting data migration for request_logs...") logrus.Info("Old schema detected. Starting data migration for request_logs...")
if !tx.Migrator().HasColumn(&models.RequestLog{}, "group_name") { if !db.Migrator().HasColumn(&models.RequestLog{}, "group_name") {
logrus.Info("Adding 'group_name' column to request_logs table...") logrus.Info("Adding 'group_name' column to request_logs table...")
if err := tx.Migrator().AddColumn(&models.RequestLog{}, "group_name"); err != nil { if err := db.Migrator().AddColumn(&models.RequestLog{}, "group_name"); err != nil {
return err return err // Column addition is critical
} }
} }
if !tx.Migrator().HasColumn(&models.RequestLog{}, "key_value") { if !db.Migrator().HasColumn(&models.RequestLog{}, "key_value") {
logrus.Info("Adding 'key_value' column to request_logs table...") logrus.Info("Adding 'key_value' column to request_logs table...")
if err := tx.Migrator().AddColumn(&models.RequestLog{}, "key_value"); err != nil { if err := db.Migrator().AddColumn(&models.RequestLog{}, "key_value"); err != nil {
return err return err // Column addition is critical
} }
} }
@@ -40,14 +40,15 @@ func V1_0_13_FixRequestLogs(db *gorm.DB) error {
logrus.Infof("Processing batch %d...", i+1) logrus.Infof("Processing batch %d...", i+1)
var oldLogs []OldRequestLog var oldLogs []OldRequestLog
result := tx.Model(&models.RequestLog{}). result := db.Model(&models.RequestLog{}).
Select("id", "key_id", "group_id"). Select("id", "key_id", "group_id").
Where("key_value IS NULL OR group_name IS NULL"). Where("key_value IS NULL OR group_name IS NULL").
Limit(batchSize). Limit(batchSize).
Find(&oldLogs) Find(&oldLogs)
if result.Error != nil { if result.Error != nil {
return result.Error logrus.WithError(result.Error).Error("Failed to fetch batch of logs. Skipping to next batch.")
continue
} }
if len(oldLogs) == 0 { if len(oldLogs) == 0 {
@@ -72,8 +73,8 @@ func V1_0_13_FixRequestLogs(db *gorm.DB) error {
for id := range keyIDMap { for id := range keyIDMap {
keyIDs = append(keyIDs, id) keyIDs = append(keyIDs, id)
} }
if err := tx.Model(&models.APIKey{}).Where("id IN ?", keyIDs).Find(&apiKeys).Error; err != nil { if err := db.Model(&models.APIKey{}).Where("id IN ?", keyIDs).Find(&apiKeys).Error; err != nil {
return err logrus.WithError(err).Warn("Failed to fetch API keys for the current batch. Some logs may not be updated.")
} }
} }
keyValueMapping := make(map[uint]string) keyValueMapping := make(map[uint]string)
@@ -87,8 +88,8 @@ func V1_0_13_FixRequestLogs(db *gorm.DB) error {
for id := range groupIDMap { for id := range groupIDMap {
groupIDs = append(groupIDs, id) groupIDs = append(groupIDs, id)
} }
if err := tx.Model(&models.Group{}).Where("id IN ?", groupIDs).Find(&groups).Error; err != nil { if err := db.Model(&models.Group{}).Where("id IN ?", groupIDs).Find(&groups).Error; err != nil {
return err logrus.WithError(err).Warn("Failed to fetch groups for the current batch. Some logs may not be updated.")
} }
} }
groupNameMapping := make(map[uint]string) groupNameMapping := make(map[uint]string)
@@ -96,6 +97,8 @@ func V1_0_13_FixRequestLogs(db *gorm.DB) error {
groupNameMapping[group.ID] = group.Name groupNameMapping[group.ID] = group.Name
} }
updateGroups := make(map[string]map[string][]string)
for _, logEntry := range oldLogs { for _, logEntry := range oldLogs {
groupName, gExists := groupNameMapping[logEntry.GroupID] groupName, gExists := groupNameMapping[logEntry.GroupID]
if !gExists { if !gExists {
@@ -107,24 +110,31 @@ func V1_0_13_FixRequestLogs(db *gorm.DB) error {
logrus.Warnf("Log ID %s: Could not find APIKey for key_id %d. Setting key_value to empty string.", logEntry.ID, logEntry.KeyID) logrus.Warnf("Log ID %s: Could not find APIKey for key_id %d. Setting key_value to empty string.", logEntry.ID, logEntry.KeyID)
} }
if _, ok := updateGroups[groupName]; !ok {
updateGroups[groupName] = make(map[string][]string)
}
updateGroups[groupName][keyValue] = append(updateGroups[groupName][keyValue], logEntry.ID)
}
for groupName, keyMap := range updateGroups {
for keyValue, ids := range keyMap {
updates := map[string]any{ updates := map[string]any{
"group_name": groupName, "group_name": groupName,
"key_value": keyValue, "key_value": keyValue,
} }
if err := tx.Model(&models.RequestLog{}).Where("id = ?", logEntry.ID).UpdateColumns(updates).Error; err != nil { if err := db.Model(&models.RequestLog{}).Where("id IN ?", ids).UpdateColumns(updates).Error; err != nil {
logrus.WithError(err).Errorf("Failed to update log entry with ID: %s", logEntry.ID) logrus.WithError(err).Errorf("Failed to update a batch of log entries. Skipping this batch.")
continue
} }
} }
logrus.Infof("Successfully updated %d log entries in batch %d.", len(oldLogs), i+1) }
logrus.Infof("Finished processing batch %d. Updated %d log entries.", i+1, len(oldLogs))
} }
logrus.Info("Data migration complete. Dropping 'key_id' column from request_logs table...") logrus.Info("Data migration complete. Dropping 'key_id' column from request_logs table...")
if err := tx.Migrator().DropColumn(&models.RequestLog{}, "key_id"); err != nil { if err := db.Migrator().DropColumn(&models.RequestLog{}, "key_id"); err != nil {
logrus.WithError(err).Warn("Failed to drop 'key_id' column. This can be done manually.") logrus.WithError(err).Warn("Failed to drop 'key_id' column. This can be done manually.")
} }
logrus.Info("Database migration successful!") logrus.Info("Database migration finished!")
return nil return nil
})
} }