// backfill-pinyin is a one-time migration tool that fills name_pinyin and // name_initials for products that have empty values. // Usage: go run ./cmd/backfill-pinyin package main import ( "log" "strings" "gorm.io/driver/mysql" "gorm.io/gorm" "gorm.io/gorm/logger" "github.com/spf13/viper" "github.com/wangjia/jiu/backend/internal/model" "github.com/wangjia/jiu/backend/internal/util" ) func main() { viper.SetConfigName("config") viper.SetConfigType("yaml") viper.AddConfigPath(".") viper.AddConfigPath("./config") viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) viper.AutomaticEnv() _ = viper.BindEnv("database.dsn", "DATABASE_DSN") if err := viper.ReadInConfig(); err != nil { log.Println("[config] no config file, relying on env vars") } dsn := viper.GetString("database.dsn") if dsn == "" { log.Fatal("DATABASE_DSN is required") } db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), }) if err != nil { log.Fatalf("failed to connect database: %v", err) } var products []model.Product db.Where("name_pinyin = '' OR name_pinyin IS NULL").Find(&products) if len(products) == 0 { log.Println("No products to backfill.") return } for i := range products { full, initials := util.ToPinyin(products[i].Name) db.Model(&products[i]).Updates(map[string]interface{}{ "name_pinyin": full, "name_initials": initials, }) } log.Printf("backfill-pinyin: updated %d products", len(products)) }