GORM GIN 更新查询导致 500 内部服务器错误

GORM GIN Update Query Results in 500 Internal Server Error

我正在使用 Gin 和 GORM 在 Golang 中编写一本书 API。我已成功实现 API 的创建、获取和删除部分,但更新导致 500 内部服务器错误。我正在尝试更新功能,它只更新 body(下面给出的示例)中提供的特定标签。非常感谢任何帮助或指导。

GO 日志

[31m2022/05/09 14:08:00 [Recovery] 2022/05/09 - 14:08:00 panic recovered:
PATCH /books/2 HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 66
Content-Type: text/plain;charset=UTF-8
Origin: chrome-extension://ihgpcfpkpmdcghlnaofdmjkoemnlijdi
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: none
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36


reflect: call of reflect.Value.SetString on uint Value
C:/Program Files/Go/src/reflect/value.go:221 (0xc7bb04)
        flag.mustBe: panic(&ValueError{methodName(), f.kind()})
C:/Program Files/Go/src/reflect/value.go:1747 (0xc7ba3e)
        Value.SetString: v.mustBe(String)
C:/Users/NK086843/go/pkg/mod/gorm.io/gorm@v1.23.5/schema/field.go:771 (0x10defb7)
        (*Field).setupValuerAndSetter.func11: field.ReflectValueOf(ctx, value).SetString(data)
C:/Users/NK086843/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:144 (0x115b68e)
        ConvertToAssignments.func2: field.Set(stmt.Context, stmt.ReflectValue, value)
C:/Users/NK086843/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:275 (0x11534f9)
        ConvertToAssignments: assignValue(field, value)
C:/Users/NK086843/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:73 (0x115ac9e)
        Update.func1: if set := ConvertToAssignments(db.Statement); len(set) != 0 {
C:/Users/NK086843/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks.go:130 (0x10ebe14)
        (*processor).Execute: f(db)
C:/Users/NK086843/go/pkg/mod/gorm.io/gorm@v1.23.5/finisher_api.go:372 (0x10f4e8d)
        (*DB).Updates: return tx.callbacks.Update().Execute(tx)
C:/New folder/golang/github.com/shashank-kakarla/BookAPI/controllers/books.go:101 (0x1167007)
        UpdateBook: models.DB.Model(&book).Updates(input)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x10917e1)
        (*Context).Next: c.handlers[c.index](c)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/recovery.go:99 (0x10917c7)
        CustomRecoveryWithWriter.func1: c.Next()
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x10908c6)
        (*Context).Next: c.handlers[c.index](c)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/logger.go:241 (0x1090885)
        LoggerWithConfig.func1: c.Next()
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x1086689)
        (*Context).Next: c.handlers[c.index](c)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:555 (0x108666f)
        (*Engine).handleHTTPRequest: c.Next()
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:511 (0x1086112)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Program Files/Go/src/net/http/server.go:2867 (0xe76e29)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Program Files/Go/src/net/http/server.go:1932 (0xe721ac)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Program Files/Go/src/runtime/asm_amd64.s:1371 (0xc3d900)
        goexit: BYTE    [=10=]x90   // NOP
←[0m
[GIN] 2022/05/09 - 14:08:00 |←[97;41m 500 ←[0m|     19.7185ms |       127.0.0.1 |←[97;42m PATCH   ←[0m "/books/2"

GO 模型

func UpdateBook(c *gin.Context) {
    // Get model if exist
    var book models.Book
    if err := models.DB.Where("id = ?", c.Param("id")).First(&book).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
        return
    }

    // Validate input
    var input UpdateBookInput
    if err := c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    models.DB.Model(&book).Updates(input)

    c.JSON(http.StatusOK, gin.H{"data": book})
}

UpdateBookInput 结构

type UpdateBookInput struct {
    Title  string `json:"title"`
    Author string `json:"author"`
}

main.go

func main() {

    router := gin.Default()

    models.ConnectDatabase()

    router.GET("/books", controllers.FetchBooks)
    router.GET("/books/:id", controllers.FindBookByID)
    router.GET("/books/title/:title", controllers.FindBookByTitle)
    router.GET("/books/author/:author", controllers.FindBookByAuthor)

    router.POST("/books", controllers.CreateBook)

    router.PATCH("/books/:id", controllers.UpdateBook)

    router.DELETE("/books/:id", controllers.RemoveBook)

    router.Run()
}

请求URL和Body URL

PATCH http://127.0.0.1:8080/books/2

BODY

{
    "title": "Breaking Dawn",
}

Schema/Model

package models

type Book struct {
    ID     uint   `json:"id" gorm:"primary_key"`
    Title  string `json:"title"`
    Author string `json:"author"`
}

不是直接传递 UpdateBookInput 对象,而是将其转换为 models.Book 对象。

我想 JSON 数据包含一个字符串类型的 ID 字段,因为这里唯一的 uint 字段是 ID。要么 gorm 对更新或类似的东西表现得很奇怪。

确保输入是干净的。