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 对更新或类似的东西表现得很奇怪。
确保输入是干净的。
我正在使用 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 对更新或类似的东西表现得很奇怪。
确保输入是干净的。