從 v1 升級到 v2 後 Golang Gorm 範圍被破壞
P粉005417748
P粉005417748 2024-02-03 17:53:53
0
1
469

我使用的是 Gorm v1。我的分頁範圍可以正常運作:

func Paginate(entity BaseEntity, p *Pagination) func(db *gorm.DB) *gorm.DB {
    return func(db *gorm.DB) *gorm.DB {
        var totalRows int64

        db.Model(entity).Count(&totalRows)
        
        totalPages := int(math.Ceil(float64(totalRows) / float64(p.PerPage)))
        p.TotalPages = totalPages
        p.TotalCount = int(totalRows)
        p.SetLinks(entity.ResourceName())

        return db.Offset(p.Offset).Limit(p.PerPage)
    }
}

以及我的稱呼方式:

if err := gs.db.Scopes(entities.Paginate(genre, p)).Find(&gs.Genres).Error; err != nil {
        return errors.New(err.Error())
    }

同樣,這曾經可以正常工作,直到我升級到 Gorm v2。現在我收到以下訊息:

[0.204ms] [行:2] 從 genres LIMIT 2 中選擇 * sql:掃描中預期有9 個目標參數,而不是1;sql:掃描中預期有9 個目標參數,而不是 1[GIN] 2022/06/18 - 00:41:00 | 400 | 1.5205 毫秒| 127.0 .0.1 |取得“/api/v1/流派” 錯誤 #01:sql:掃描中預期有 9 個目標參數,而不是 1;sql:掃描中預期有 9 個目標參數,而不是 1

現在,我發現錯誤是由於這一行引起的: db.Model(實體).Count(&totalRows) 因為如果我刪除它,那麼我的查詢就會正確執行(顯然 TotalPages 的資料不正確,因為它沒有計算)。瀏覽文檔,我看到https://gorm.io/docs/method_chaining.html#Multiple-Immediate-Methods,所以我的猜測是用於獲取totalRows 的連接正在被重用並且有一些殘留數據,因此我的偏移量和限制查詢正在失敗。 我嘗試為計數和偏移查詢建立一個新會話: db.Model(entity).Count(&totalRows).Session(&gorm.Session{})

#return db.Offset(p.Offset).Limit(p.PerPage).Session(&gorm.Session{})

希望每個人都能使用自己的會話,但似乎行不通。

有什麼建議嗎?

P粉005417748
P粉005417748

全部回覆(1)
P粉465287592

如果有人需要它:

我確實必須創建一個新會話,但我沒有以正確的方式創建它。我最終做了:

countDBSession := db.Session(&gorm.Session{Initialized: true})
countDBSession.Model(entity).Count(&totalRows)

效果如預期的。所以我現在的範圍是:

// Paginate is a Gorm scope function.
func Paginate(entity BaseEntity, p *Pagination) func(db *gorm.DB) *gorm.DB {
    return func(db *gorm.DB) *gorm.DB {

        var totalRows int64

        // we must create a new session to run the count, otherwise by using the same db connection
        // we'll get some residual data which will cause db.Offset(p.Offset).Limit(p.PerPage) to fail.
        countDBSession := db.Session(&gorm.Session{Initialized: true})
        countDBSession.Model(entity).Count(&totalRows)

        totalPages := int(math.Ceil(float64(totalRows) / float64(p.PerPage)))
        p.TotalPages = totalPages
        p.TotalCount = int(totalRows)
        p.SetLinks(entity.ResourceName())

        return db.Offset(p.Offset).Limit(p.PerPage)
    }
}

請注意,我正在使用新會話透過countDBSession 取得計數,這不會影響*db.Gorm 參數在return db.Offset(p.Offset) .Limit(p.PerPage) 的使用).Session(&gorm.Session{})

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!