@@ -111,82 +111,87 @@ func main() {
111111 }
112112 slog .Info ("Filtered migratable columns" , "count" , len (columnsToMigrate ), "skipped" , len (allColumns )- len (columnsToMigrate ))
113113
114- // Execute all migrations in a single transaction
115- err = dbForMigration .Transaction (func (tx * gorm.DB ) error {
116- // Step 1: Drop all generated columns (they block type changes)
117- slog .Info ("Dropping all generated columns" )
118- if err := dao .DropAllGeneratedColumns (tx ); err != nil {
119- return fmt .Errorf ("failed to drop generated columns: %w" , err )
120- }
121- slog .Info ("All generated columns dropped" )
122-
123- // Step 2: Clean orphaned foreign keys (пока FK ещё существуют в БД)
124- slog .Info ("Cleaning orphaned foreign keys" )
125- if err := dao .CleanAllOrphanedForeignKeys (tx ); err != nil {
126- return fmt .Errorf ("failed to clean all orphaned foreign keys: %w" , err )
127- }
128- slog .Info ("All orphaned foreign keys cleaned" )
114+ // Пропускаем UUID миграцию если нет колонок для миграции
115+ if len (columnsToMigrate ) > 0 {
116+ // Execute all migrations in a single transaction
117+ err = dbForMigration .Transaction (func (tx * gorm.DB ) error {
118+ // Step 1: Drop all generated columns (they block type changes)
119+ slog .Info ("Dropping all generated columns" )
120+ if err := dao .DropAllGeneratedColumns (tx ); err != nil {
121+ return fmt .Errorf ("failed to drop generated columns: %w" , err )
122+ }
123+ slog .Info ("All generated columns dropped" )
129124
130- // Step 3: Drop all FK constraints
131- slog .Info ("Dropping all foreign key constraints " )
132- if err := dao .DropAllForeignKeys (tx ); err != nil {
133- return fmt .Errorf ("failed to drop foreign keys: %w" , err )
134- }
135- slog .Info ("All foreign key constraints dropped " )
125+ // Step 2: Clean orphaned foreign keys (пока FK ещё существуют в БД)
126+ slog .Info ("Cleaning orphaned foreign keys " )
127+ if err := dao .CleanAllOrphanedForeignKeys (tx ); err != nil {
128+ return fmt .Errorf ("failed to clean all orphaned foreign keys: %w" , err )
129+ }
130+ slog .Info ("All orphaned foreign keys cleaned " )
136131
137- // Step 4 : Drop all CHECK constraints (including linked_issues check:id1<id2)
138- slog .Info ("Dropping all check constraints" )
139- if err := dao .DropAllCheckConstraints (tx ); err != nil {
140- return fmt .Errorf ("failed to drop check constraints : %w" , err )
141- }
142- slog .Info ("All check constraints dropped" )
132+ // Step 3 : Drop all FK constraints
133+ slog .Info ("Dropping all foreign key constraints" )
134+ if err := dao .DropAllForeignKeys (tx ); err != nil {
135+ return fmt .Errorf ("failed to drop foreign keys : %w" , err )
136+ }
137+ slog .Info ("All foreign key constraints dropped" )
143138
144- // Step 5: Clean invalid UUIDs (set to NULL)
145- slog .Info ("Cleaning invalid UUID values" , "count" , len (columnsToMigrate ))
146- for _ , col := range columnsToMigrate {
147- if err := dao .CleanInvalidUUIDs (tx , col .Table , col .Column ); err != nil {
148- return fmt .Errorf ("failed to clean invalid UUIDs in %s.%s: %w" , col .Table , col .Column , err )
139+ // Step 4: Drop all CHECK constraints (including linked_issues check:id1<id2)
140+ slog .Info ("Dropping all check constraints" )
141+ if err := dao .DropAllCheckConstraints (tx ); err != nil {
142+ return fmt .Errorf ("failed to drop check constraints: %w" , err )
149143 }
150- }
151- slog .Info ("All invalid UUIDs cleaned" )
152-
153- // Step 6: Replace column types
154- slog .Info ("Replacing column types" , "count" , len (columnsToMigrate ))
155- for _ , col := range columnsToMigrate {
156- slog .Info ("Migrating column" , "table" , col .Table , "column" , col .Column , "currentType" , col .CurrentType )
157- if err := utils .ReplaceColumnTypeWithCast (tx , col , "uuid" ); err != nil {
158- return fmt .Errorf ("failed to replace column %s.%s (type %s): %w" , col .Table , col .Column , col .CurrentType , err )
144+ slog .Info ("All check constraints dropped" )
145+
146+ // Step 5: Clean invalid UUIDs (set to NULL)
147+ slog .Info ("Cleaning invalid UUID values" , "count" , len (columnsToMigrate ))
148+ for _ , col := range columnsToMigrate {
149+ if err := dao .CleanInvalidUUIDs (tx , col .Table , col .Column ); err != nil {
150+ return fmt .Errorf ("failed to clean invalid UUIDs in %s.%s: %w" , col .Table , col .Column , err )
151+ }
159152 }
160- }
161- slog .Info ("All column types replaced successfully" )
162-
163- // Step 7: Clean known self-referencing FK (они могли не существовать в БД)
164- slog .Info ("Cleaning known self-referencing foreign keys" )
165- selfRefFKs := []struct {
166- Table string
167- Column string
168- ReferencedTable string
169- ReferencedColumn string
170- }{
171- {"issues" , "parent_id" , "issues" , "id" },
172- {"docs" , "parent_id" , "docs" , "id" },
173- {"doc_fields" , "parent_id" , "doc_fields" , "id" },
174- }
175- for _ , fk := range selfRefFKs {
176- if err := dao .CleanOrphanedForeignKeys (tx , fk .Table , fk .Column , fk .ReferencedTable , fk .ReferencedColumn ); err != nil {
177- slog .Warn ("Failed to clean self-referencing FK" , "table" , fk .Table , "column" , fk .Column , "err" , err )
153+ slog .Info ("All invalid UUIDs cleaned" )
154+
155+ // Step 6: Replace column types
156+ slog .Info ("Replacing column types" , "count" , len (columnsToMigrate ))
157+ for _ , col := range columnsToMigrate {
158+ slog .Info ("Migrating column" , "table" , col .Table , "column" , col .Column , "currentType" , col .CurrentType )
159+ if err := utils .ReplaceColumnTypeWithCast (tx , col , "uuid" ); err != nil {
160+ return fmt .Errorf ("failed to replace column %s.%s (type %s): %w" , col .Table , col .Column , col .CurrentType , err )
161+ }
178162 }
179- }
180- slog .Info ("Self-referencing foreign keys cleaned" )
163+ slog .Info ("All column types replaced successfully" )
164+
165+ // Step 7: Clean known self-referencing FK (они могли не существовать в БД)
166+ slog .Info ("Cleaning known self-referencing foreign keys" )
167+ selfRefFKs := []struct {
168+ Table string
169+ Column string
170+ ReferencedTable string
171+ ReferencedColumn string
172+ }{
173+ {"issues" , "parent_id" , "issues" , "id" },
174+ {"docs" , "parent_id" , "docs" , "id" },
175+ {"doc_fields" , "parent_id" , "doc_fields" , "id" },
176+ }
177+ for _ , fk := range selfRefFKs {
178+ if err := dao .CleanOrphanedForeignKeys (tx , fk .Table , fk .Column , fk .ReferencedTable , fk .ReferencedColumn ); err != nil {
179+ slog .Warn ("Failed to clean self-referencing FK" , "table" , fk .Table , "column" , fk .Column , "err" , err )
180+ }
181+ }
182+ slog .Info ("Self-referencing foreign keys cleaned" )
181183
182- return nil
183- })
184+ return nil
185+ })
184186
185- if err != nil {
186- slog .Error ("UUID migration failed" , "err" , err )
187- os .Exit (1 )
187+ if err != nil {
188+ slog .Error ("UUID migration failed" , "err" , err )
189+ os .Exit (1 )
190+ }
191+ slog .Info ("UUID migration completed successfully" )
192+ } else {
193+ slog .Info ("No UUID columns need migration, skipping UUID migration steps" )
188194 }
189- slog .Info ("UUID migration completed successfully" )
190195
191196 // Step 8: AutoMigrate models (в отдельной транзакции)
192197 err = dbForMigration .Transaction (func (tx * gorm.DB ) error {
0 commit comments