Cheug's Blog

当前位置:网站首页 / golang / 正文

杰奇cms1.7 articlenamepy字段 拼音化脚本

2024-12-04 / golang / 63 次围观 / 0 次吐槽 /

安装必要的依赖:

go mod init myproject
go get github.com/go-sql-driver/mysql
go get github.com/mozillazg/go-pinyin

完整的程序代码:

package main

import (
    "database/sql"
    "fmt"
    "log"
    "strings"
    "unicode"

    _ "github.com/go-sql-driver/mysql"
    "github.com/mozillazg/go-pinyin"
)

func main() {
    // 配置数据库连接信息
    dsn := "数据库用户:密码@tcp(ip:3306)/数据库名"
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        log.Fatal("数据库连接失败:", err)
    }
    defer db.Close()

    // 查询 articlenamepy 为空的记录
    rows, err := db.Query("SELECT articleid, articlename FROM jieqi_article_article WHERE articlenamepy IS NULL OR articlenamepy = ''")
    if err != nil {
        log.Fatal("查询失败:", err)
    }
    defer rows.Close()

    // 创建拼音转换器
    args := pinyin.NewArgs()
    args.Style = args.Style = pinyin.FirstLetter // 使用首字母模式,你也可以改为 pinyin.Normal 获取完整拼音 

    // 处理每一行数据
    for rows.Next() {
        var id int
        var articlename string
        if err := rows.Scan(&id, &articlename); err != nil {
            log.Printf("读取行数据失败: %v", err)
            continue
        }

        // 将中文转换为拼音
        pinyinSlice := pinyin.Pinyin(articlename, args)

        var finalPinyin string
        if len(pinyinSlice) == 0 {
            // 如果没有中文字符,只保留英文和数字
            var filtered []rune
            for _, r := range articlename {
                if unicode.IsLetter(r) || unicode.IsNumber(r) {
                    filtered = append(filtered, r)
                }
            }
            finalPinyin = string(filtered)
        } else {
            // 将拼音数组转换为字符串
            var pinyinStr []string
            for _, p := range pinyinSlice {
                if len(p) > 0 {
                    pinyinStr = append(pinyinStr, p[0])
                }
            }
            finalPinyin = strings.Join(pinyinStr, "")
        }

        // 如果过滤后结果为空,设为空字符串
        if finalPinyin == "" {
            finalPinyin = ""
        }

        // 更新数据库
        _, err = db.Exec("UPDATE jieqi_article_article SET articlenamepy = ? WHERE articleid = ?", finalPinyin, id)
        if err != nil {
            log.Printf("更新ID %d 失败: %v", id, err)
            continue
        }

        fmt.Printf("成功更新 ID: %d, 原文: %s, 拼音: %s\n", id, articlename, finalPinyin)
    }

    if err = rows.Err(); err != nil {
        log.Fatal("遍历结果集时发生错误:", err)
    }
}

修改articlenamepy重复值

package main

import (
    "database/sql"
    "fmt"
    "log"
    "strconv"
    "time"

    _ "github.com/go-sql-driver/mysql"
)

func main() {
    // 配置数据库连接信息
    dsn := "数据库用户:密码@tcp(ip:3306)/数据库?timeout=60s&readTimeout=60s&writeTimeout=60s&parseTime=true&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci&maxAllowedPacket=0&interpolateParams=true"

    // 创建数据库连接池
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        log.Fatal("数据库连接失败:", err)
    }
    defer db.Close()

    // 设置更保守的连接池参数
    db.SetMaxOpenConns(5)
    db.SetMaxIdleConns(2)
    db.SetConnMaxLifetime(time.Minute * 3)
    db.SetConnMaxIdleTime(time.Minute)

    // 测试连接
    if err := db.Ping(); err != nil {
        log.Fatal("数据库连接测试失败:", err)
    }

    // 查询重复的 articlenamepy 值
    rows, err := db.Query(`
        SELECT articlenamepy, COUNT(*) as count
        FROM jieqi_article_article 
        WHERE articlenamepy != ''
        GROUP BY articlenamepy 
        HAVING COUNT(*) > 1
    `)
    if err != nil {
        log.Fatal("查询失败:", err)
    }
    defer rows.Close()

    // 处理每组重复的记录
    for rows.Next() {
        var articlenamepy string
        var count int
        if err := rows.Scan(&articlenamepy, &count); err != nil {
            log.Printf("读取行数据失败: %v", err)
            continue
        }

        // 处理每组重复记录
        if err := processGroup(db, articlenamepy); err != nil {
            log.Printf("处理组 %s 失败: %v", articlenamepy, err)
        }
    }

    if err = rows.Err(); err != nil {
        log.Fatal("遍历结果集时发生错误:", err)
    }
}

func processGroup(db *sql.DB, articlenamepy string) error {
    // 查询具体的记录
    rows, err := db.Query(`
        SELECT articleid, articlenamepy 
        FROM jieqi_article_article 
        WHERE articlenamepy = ? 
        ORDER BY articleid
    `, articlenamepy)
    if err != nil {
        return fmt.Errorf("查询详细记录失败: %v", err)
    }
    defer rows.Close()

    // 处理每条重复记录
    index := 0
    var records []struct {
        id        int
        namepy    string
        newNamepy string
    }

    // 首先收集所有需要更新的记录
    for rows.Next() {
        var articleid int
        var currentNamepy string
        if err := rows.Scan(&articleid, &currentNamepy); err != nil {
            return fmt.Errorf("读取详细记录失败: %v", err)
        }

        if index > 0 {
            records = append(records, struct {
                id        int
                namepy    string
                newNamepy string
            }{
                id:        articleid,
                namepy:    currentNamepy,
                newNamepy: articlenamepy + strconv.Itoa(index),
            })
        }
        index++
    }

    // 然后逐个更新记录,每个更新都有重试机制
    for _, record := range records {
        // 重试机制
        maxRetries := 3
        for retry := 0; retry < maxRetries; retry++ {
            err := updateRecord(db, record.id, record.newNamepy)
            if err != nil {
                log.Printf("更新记录失败 (ID: %d) (重试 %d/%d): %v",
                    record.id, retry+1, maxRetries, err)
                if retry < maxRetries-1 {
                    time.Sleep(time.Second * 2)
                    continue
                }
                return err
            }
            fmt.Printf("成功更新记录: ID=%d, 原值=%s, 新值=%s\n",
                record.id, record.namepy, record.newNamepy)
            break
        }
    }

    return nil
}

func updateRecord(db *sql.DB, articleid int, newNamepy string) error {
    _, err := db.Exec(`
        UPDATE jieqi_article_article 
        SET articlenamepy = ? 
        WHERE articleid = ?
    `, newNamepy, articleid)
    if err != nil {
        return fmt.Errorf("更新失败: %v", err)
    }
    return nil
}


Powered By Cheug's Blog

Copyright Cheug Rights Reserved.