版本化数据库迁移系统:schema_migrations 表 + DBMigration 注册表,DBv1 修复 channel_id TEXT->VARCHAR(255) 解决 MySQL Error 1170

This commit is contained in:
2026-08-07 19:26:18 +08:00
parent d919ea2c53
commit 4ce341208b
+57 -1
View File
@@ -439,7 +439,7 @@ type TextMessageRecord struct {
Text *string `gorm:"column:text"` Text *string `gorm:"column:text"`
PayloadHex *string `gorm:"column:payload_hex"` PayloadHex *string `gorm:"column:payload_hex"`
Topic string `gorm:"column:topic;not null"` Topic string `gorm:"column:topic;not null"`
ChannelID *string `gorm:"column:channel_id;index:idx_text_message_channel_id_created_at,priority:1"` ChannelID *string `gorm:"column:channel_id;type:varchar(255);index:idx_text_message_channel_id_created_at,priority:1"`
GatewayID *string `gorm:"column:gateway_id"` GatewayID *string `gorm:"column:gateway_id"`
PacketID *int64 `gorm:"column:packet_id;index:idx_text_message_packet_id"` PacketID *int64 `gorm:"column:packet_id;index:idx_text_message_packet_id"`
PacketTo *string `gorm:"column:packet_to"` PacketTo *string `gorm:"column:packet_to"`
@@ -465,6 +465,15 @@ func (TextMessageRecord) TableName() string {
return "text_message" return "text_message"
} }
type SchemaMigration struct {
Version int `gorm:"column:version;primaryKey"`
AppliedAt time.Time `gorm:"column:applied_at;autoCreateTime"`
}
func (SchemaMigration) TableName() string {
return "schema_migrations"
}
// LLMProviderRecord 保存 LLM API 配置,支持多个 AI 提供商 // LLMProviderRecord 保存 LLM API 配置,支持多个 AI 提供商
type LLMProviderRecord struct { type LLMProviderRecord struct {
Name string `gorm:"column:name;primaryKey;size:64;not null"` // 配置名称,如 "default"、"openai"、"ark" 等 Name string `gorm:"column:name;primaryKey;size:64;not null"` // 配置名称,如 "default"、"openai"、"ark" 等
@@ -702,6 +711,9 @@ func (s *Store) migrate() error {
} }
} }
} }
if err := runDBMigrations(tx, s.driver); err != nil {
return err
}
for _, item := range []struct { for _, item := range []struct {
label string label string
model any model any
@@ -878,6 +890,50 @@ func createMissingIndexes(migrator gorm.Migrator, model any, label string, index
return nil return nil
} }
type DBMigration struct {
Version int
Up func(tx *gorm.DB, driver string) error
}
var dbMigrations = []DBMigration{
{Version: 1, Up: migrateDB1},
}
func migrateDB1(tx *gorm.DB, driver string) error {
if driver == config.DriverMySQL {
if err := tx.Exec("ALTER TABLE text_message MODIFY COLUMN channel_id VARCHAR(255)").Error; err != nil {
return fmt.Errorf("alter text_message.channel_id to varchar: %w", err)
}
}
return nil
}
func runDBMigrations(tx *gorm.DB, driver string) error {
if !tx.Migrator().HasTable(&SchemaMigration{}) {
if err := tx.Migrator().CreateTable(&SchemaMigration{}); err != nil {
return fmt.Errorf("create schema_migrations table: %w", err)
}
}
applied := make(map[int]bool)
var rows []SchemaMigration
tx.Find(&rows)
for _, r := range rows {
applied[r.Version] = true
}
for _, m := range dbMigrations {
if applied[m.Version] {
continue
}
if err := m.Up(tx, driver); err != nil {
return fmt.Errorf("db migration %d: %w", m.Version, err)
}
if err := tx.Create(&SchemaMigration{Version: m.Version}).Error; err != nil {
return fmt.Errorf("record db migration %d: %w", m.Version, err)
}
}
return nil
}
func (s *Store) UpsertNodeInfo(record map[string]any) error { func (s *Store) UpsertNodeInfo(record map[string]any) error {
node, err := nodeInfoFromRecord(record) node, err := nodeInfoFromRecord(record)
if err != nil { if err != nil {