@@ -7,124 +7,134 @@ import (
77 "gorm.io/gorm"
88)
99
10+ // TODO: 更新迁移,待多个版本后旧版本都升级差不多之后移除。
1011func V1_0_13_FixRequestLogs (db * gorm.DB ) error {
11- return db .Transaction (func (tx * gorm.DB ) error {
12- // 如果有key_id,就执行修复
13- if ! tx .Migrator ().HasColumn (& models.RequestLog {}, "key_id" ) {
14- return nil
15- }
12+ // 如果有key_id,就执行修复
13+ if ! db .Migrator ().HasColumn (& models.RequestLog {}, "key_id" ) {
14+ return nil
15+ }
1616
17- logrus .Info ("Old schema detected. Starting data migration for request_logs..." )
17+ logrus .Info ("Old schema detected. Starting data migration for request_logs..." )
1818
19- if ! tx .Migrator ().HasColumn (& models.RequestLog {}, "group_name" ) {
20- logrus .Info ("Adding 'group_name' column to request_logs table..." )
21- if err := tx .Migrator ().AddColumn (& models.RequestLog {}, "group_name" ); err != nil {
22- return err
23- }
19+ if ! db .Migrator ().HasColumn (& models.RequestLog {}, "group_name" ) {
20+ logrus .Info ("Adding 'group_name' column to request_logs table..." )
21+ if err := db .Migrator ().AddColumn (& models.RequestLog {}, "group_name" ); err != nil {
22+ return err // Column addition is critical
2423 }
25- if ! tx . Migrator (). HasColumn ( & models. RequestLog {}, "key_value" ) {
26- logrus . Info ( "Adding 'key_value' column to request_logs table..." )
27- if err := tx . Migrator (). AddColumn ( & models. RequestLog {}, " key_value" ); err != nil {
28- return err
29- }
24+ }
25+ if ! db . Migrator (). HasColumn ( & models. RequestLog {}, "key_value" ) {
26+ logrus . Info ( "Adding ' key_value' column to request_logs table..." )
27+ if err := db . Migrator (). AddColumn ( & models. RequestLog {}, "key_value" ); err != nil {
28+ return err // Column addition is critical
3029 }
31-
32- type OldRequestLog struct {
33- ID string
34- KeyID uint `gorm:"column:key_id"`
35- GroupID uint
30+ }
31+
32+ type OldRequestLog struct {
33+ ID string
34+ KeyID uint `gorm:"column:key_id"`
35+ GroupID uint
36+ }
37+
38+ batchSize := 1000
39+ for i := 0 ; ; i ++ {
40+ logrus .Infof ("Processing batch %d..." , i + 1 )
41+ var oldLogs []OldRequestLog
42+
43+ result := db .Model (& models.RequestLog {}).
44+ Select ("id" , "key_id" , "group_id" ).
45+ Where ("key_value IS NULL OR group_name IS NULL" ).
46+ Limit (batchSize ).
47+ Find (& oldLogs )
48+
49+ if result .Error != nil {
50+ logrus .WithError (result .Error ).Error ("Failed to fetch batch of logs. Skipping to next batch." )
51+ continue
3652 }
3753
38- batchSize := 1000
39- for i := 0 ; ; i ++ {
40- logrus .Infof ("Processing batch %d..." , i + 1 )
41- var oldLogs []OldRequestLog
42-
43- result := tx .Model (& models.RequestLog {}).
44- Select ("id" , "key_id" , "group_id" ).
45- Where ("key_value IS NULL OR group_name IS NULL" ).
46- Limit (batchSize ).
47- Find (& oldLogs )
54+ if len (oldLogs ) == 0 {
55+ logrus .Info ("All batches processed." )
56+ break
57+ }
4858
49- if result .Error != nil {
50- return result .Error
59+ keyIDMap := make (map [uint ]bool )
60+ groupIDMap := make (map [uint ]bool )
61+ for _ , logEntry := range oldLogs {
62+ if logEntry .KeyID > 0 {
63+ keyIDMap [logEntry .KeyID ] = true
5164 }
52-
53- if len (oldLogs ) == 0 {
54- logrus .Info ("All batches processed." )
55- break
65+ if logEntry .GroupID > 0 {
66+ groupIDMap [logEntry .GroupID ] = true
5667 }
68+ }
5769
58- keyIDMap := make (map [uint ]bool )
59- groupIDMap := make (map [uint ]bool )
60- for _ , logEntry := range oldLogs {
61- if logEntry .KeyID > 0 {
62- keyIDMap [logEntry .KeyID ] = true
63- }
64- if logEntry .GroupID > 0 {
65- groupIDMap [logEntry .GroupID ] = true
66- }
70+ var apiKeys []models.APIKey
71+ if len (keyIDMap ) > 0 {
72+ var keyIDs []uint
73+ for id := range keyIDMap {
74+ keyIDs = append (keyIDs , id )
75+ }
76+ if err := db .Model (& models.APIKey {}).Where ("id IN ?" , keyIDs ).Find (& apiKeys ).Error ; err != nil {
77+ logrus .WithError (err ).Warn ("Failed to fetch API keys for the current batch. Some logs may not be updated." )
6778 }
79+ }
80+ keyValueMapping := make (map [uint ]string )
81+ for _ , key := range apiKeys {
82+ keyValueMapping [key .ID ] = key .KeyValue
83+ }
6884
69- var apiKeys []models.APIKey
70- if len (keyIDMap ) > 0 {
71- var keyIDs []uint
72- for id := range keyIDMap {
73- keyIDs = append (keyIDs , id )
74- }
75- if err := tx .Model (& models.APIKey {}).Where ("id IN ?" , keyIDs ).Find (& apiKeys ).Error ; err != nil {
76- return err
77- }
85+ var groups []models.Group
86+ if len (groupIDMap ) > 0 {
87+ var groupIDs []uint
88+ for id := range groupIDMap {
89+ groupIDs = append (groupIDs , id )
7890 }
79- keyValueMapping := make (map [uint ]string )
80- for _ , key := range apiKeys {
81- keyValueMapping [key .ID ] = key .KeyValue
91+ if err := db .Model (& models.Group {}).Where ("id IN ?" , groupIDs ).Find (& groups ).Error ; err != nil {
92+ logrus .WithError (err ).Warn ("Failed to fetch groups for the current batch. Some logs may not be updated." )
8293 }
94+ }
95+ groupNameMapping := make (map [uint ]string )
96+ for _ , group := range groups {
97+ groupNameMapping [group .ID ] = group .Name
98+ }
8399
84- var groups []models.Group
85- if len (groupIDMap ) > 0 {
86- var groupIDs []uint
87- for id := range groupIDMap {
88- groupIDs = append (groupIDs , id )
89- }
90- if err := tx .Model (& models.Group {}).Where ("id IN ?" , groupIDs ).Find (& groups ).Error ; err != nil {
91- return err
92- }
93- }
94- groupNameMapping := make (map [uint ]string )
95- for _ , group := range groups {
96- groupNameMapping [group .ID ] = group .Name
100+ updateGroups := make (map [string ]map [string ][]string )
101+
102+ for _ , logEntry := range oldLogs {
103+ groupName , gExists := groupNameMapping [logEntry .GroupID ]
104+ if ! gExists {
105+ logrus .Warnf ("Log ID %s: Could not find Group for group_id %d. Setting group_name to empty string." , logEntry .ID , logEntry .GroupID )
97106 }
98107
99- for _ , logEntry := range oldLogs {
100- groupName , gExists := groupNameMapping [logEntry .GroupID ]
101- if ! gExists {
102- logrus .Warnf ("Log ID %s: Could not find Group for group_id %d. Setting group_name to empty string." , logEntry .ID , logEntry .GroupID )
103- }
108+ keyValue , kExists := keyValueMapping [logEntry .KeyID ]
109+ if ! kExists {
110+ logrus .Warnf ("Log ID %s: Could not find APIKey for key_id %d. Setting key_value to empty string." , logEntry .ID , logEntry .KeyID )
111+ }
104112
105- keyValue , kExists := keyValueMapping [logEntry .KeyID ]
106- if ! kExists {
107- logrus .Warnf ("Log ID %s: Could not find APIKey for key_id %d. Setting key_value to empty string." , logEntry .ID , logEntry .KeyID )
108- }
113+ if _ , ok := updateGroups [groupName ]; ! ok {
114+ updateGroups [groupName ] = make (map [string ][]string )
115+ }
116+ updateGroups [groupName ][keyValue ] = append (updateGroups [groupName ][keyValue ], logEntry .ID )
117+ }
109118
119+ for groupName , keyMap := range updateGroups {
120+ for keyValue , ids := range keyMap {
110121 updates := map [string ]any {
111122 "group_name" : groupName ,
112123 "key_value" : keyValue ,
113124 }
114- if err := tx .Model (& models.RequestLog {}).Where ("id = ?" , logEntry .ID ).UpdateColumns (updates ).Error ; err != nil {
115- logrus .WithError (err ).Errorf ("Failed to update log entry with ID: %s" , logEntry .ID )
116- continue
125+ if err := db .Model (& models.RequestLog {}).Where ("id IN ?" , ids ).UpdateColumns (updates ).Error ; err != nil {
126+ logrus .WithError (err ).Errorf ("Failed to update a batch of log entries. Skipping this batch." )
117127 }
118128 }
119- logrus .Infof ("Successfully updated %d log entries in batch %d." , len (oldLogs ), i + 1 )
120129 }
130+ logrus .Infof ("Finished processing batch %d. Updated %d log entries." , i + 1 , len (oldLogs ))
131+ }
121132
122- logrus .Info ("Data migration complete. Dropping 'key_id' column from request_logs table..." )
123- if err := tx .Migrator ().DropColumn (& models.RequestLog {}, "key_id" ); err != nil {
124- logrus .WithError (err ).Warn ("Failed to drop 'key_id' column. This can be done manually." )
125- }
133+ logrus .Info ("Data migration complete. Dropping 'key_id' column from request_logs table..." )
134+ if err := db .Migrator ().DropColumn (& models.RequestLog {}, "key_id" ); err != nil {
135+ logrus .WithError (err ).Warn ("Failed to drop 'key_id' column. This can be done manually." )
136+ }
126137
127- logrus .Info ("Database migration successful!" )
128- return nil
129- })
138+ logrus .Info ("Database migration finished!" )
139+ return nil
130140}
0 commit comments