fix(database): 修复空库基线迁移因索引命名不一致而失败
GORM 1.30 AutoMigrate 对已存在表的唯一索引执行 `DROP INDEX uni_<表>_<列>`, 而建表阶段用的是 idx_ 前缀,索引名永不匹配,空库执行基线必然以 Error 1091 (Can't DROP ...; check that column/key exists) 失败。 - 新增 indexNamedNaming,令 UniqueName 复用 IndexName 的 idx_ 命名 - BootstrapSchema 改为一次性 AutoMigrate(allModels...), 让 GORM 在外键依赖排序生效(如 asset_cloud_regions 先于 asset_servers) // Logan.Li
This commit is contained in:
1 parent
0996d8a839
commit
93abf81e40
1 file changed
+19
-4
@@ -14,6 +14,7 @@ import (
|
|||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/logger"
|
"gorm.io/gorm/logger"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New 创建数据库连接
|
// New 创建数据库连接
|
||||||
@@ -51,6 +52,7 @@ func New(cfg config.DatabaseConfig) (*gorm.DB, error) {
|
|||||||
|
|
||||||
db, err := gorm.Open(dialector, &gorm.Config{
|
db, err := gorm.Open(dialector, &gorm.Config{
|
||||||
Logger: logger.Default.LogMode(logger.Silent),
|
Logger: logger.Default.LogMode(logger.Silent),
|
||||||
|
NamingStrategy: indexNamedNaming{},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -69,6 +71,19 @@ func New(cfg config.DatabaseConfig) (*gorm.DB, error) {
|
|||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// indexNamedNaming 让唯一索引与普通索引使用同一套命名规则(idx_ 前缀)。
|
||||||
|
// GORM 1.30 的 AutoMigrate 在表已存在时会对唯一索引列执行 `DROP INDEX uni_<表>_<列>`
|
||||||
|
// (NamingStrategy.UniqueName 用 uni_ 前缀),而建表实际使用 `idx_<表>_<列>`,
|
||||||
|
// 索引名永远不匹配,空库执行基线必然以 1091 失败。 // Logan.Li
|
||||||
|
type indexNamedNaming struct {
|
||||||
|
schema.NamingStrategy
|
||||||
|
}
|
||||||
|
|
||||||
|
// UniqueName 保持与 IndexName 一致,避免 AutoMigrate 误删不存在的唯一索引。
|
||||||
|
func (n indexNamedNaming) UniqueName(table, column string) string {
|
||||||
|
return n.NamingStrategy.IndexName(table, column)
|
||||||
|
}
|
||||||
|
|
||||||
// BootstrapSchema 为空数据库创建初始基线结构。
|
// BootstrapSchema 为空数据库创建初始基线结构。
|
||||||
// 该函数只能由显式的 `aiops migrate up` 调用,服务启动路径禁止调用。 // Logan.Li
|
// 该函数只能由显式的 `aiops migrate up` 调用,服务启动路径禁止调用。 // Logan.Li
|
||||||
func BootstrapSchema(db *gorm.DB) error {
|
func BootstrapSchema(db *gorm.DB) error {
|
||||||
@@ -177,10 +192,10 @@ func BootstrapSchema(db *gorm.DB) error {
|
|||||||
&model.TraceDataSource{}, // 链路追踪数据源 Jaeger/Tempo // Logan.Li
|
&model.TraceDataSource{}, // 链路追踪数据源 Jaeger/Tempo // Logan.Li
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range allModels {
|
// 必须一次性传入全部模型:GORM 只在单次调用内做外键依赖排序
|
||||||
if err := db.AutoMigrate(m); err != nil {
|
// (如 asset_cloud_regions 必须在 asset_servers 之前建表),逐个建表会踩外键顺序问题。 // Logan.Li
|
||||||
return fmt.Errorf("创建初始基线表失败 (%T): %w", m, err)
|
if err := db.AutoMigrate(allModels...); err != nil {
|
||||||
}
|
return fmt.Errorf("创建初始基线表失败: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user