Golang GORM und Gin können kein Objekt mit Assoziation erstellen

王林
Freigeben: 2024-02-12 15:12:05
nach vorne
847 Leute haben es durchsucht

golang GORM和Gin无法创建具有关联的对象

问题内容

我使用 GORM 作为 ORM 以及我的 Golang API 来与我的数据库进行通信。

但是对于创建与数据库关联的实体,代码失败了(DB.Create(&data)):

<code>2023/11/01 20:44:14 [Recovery] 2023/11/01 - 20:44:14 panic recovered:
POST /v1/product/products HTTP/1.1
Host: localhost:8080
Accept: */*
Content-Length: 589
Content-Type: application/json
User-Agent: curl/8.4.0


runtime error: invalid memory address or nil pointer dereference
/usr/lib/go/src/runtime/panic.go:261 (0x452d97)
        panicmem: panic(memoryError)
/usr/lib/go/src/runtime/signal_unix.go:861 (0x452d65)
        sigpanic: panicmem()
/home/grimm/go/pkg/mod/gorm.io/[email&#160;protected]/finisher_api.go:18 (0x926e7c)
        (*DB).Create: if db.CreateBatchSize > 0 {
/home/grimm/Documents/beeskill/website/back_end/API_website/main.go:122 (0x99cfab)
        CreatingProduct: DB.Create(&data)
/home/grimm/go/pkg/mod/github.com/gin-gonic/[email&#160;protected]/context.go:174 (0x8c9ad9)
        (*Context).Next: c.handlers[c.index](c)
/home/grimm/go/pkg/mod/github.com/gin-gonic/[email&#160;protected]/recovery.go:102 (0x8c9ac7)
        CustomRecoveryWithWriter.func1: c.Next()
/home/grimm/go/pkg/mod/github.com/gin-gonic/[email&#160;protected]/context.go:174 (0x8c8c7d)
        (*Context).Next: c.handlers[c.index](c)
/home/grimm/go/pkg/mod/github.com/gin-gonic/[email&#160;protected]/logger.go:240 (0x8c8c4c)
        LoggerWithConfig.func1: c.Next()
/home/grimm/go/pkg/mod/github.com/gin-gonic/[email&#160;protected]/context.go:174 (0x8c7d3a)
        (*Context).Next: c.handlers[c.index](c)
/home/grimm/go/pkg/mod/github.com/gin-gonic/[email&#160;protected]/gin.go:620 (0x8c79cd)
        (*Engine).handleHTTPRequest: c.Next()
/home/grimm/go/pkg/mod/github.com/gin-gonic/[email&#160;protected]/gin.go:576 (0x8c74fc)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/lib/go/src/net/http/server.go:2938 (0x6a35ed)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/lib/go/src/net/http/server.go:2009 (0x69f4d3)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/lib/go/src/runtime/asm_amd64.s:1650 (0x46ed20)
        goexit: BYTE    $0x90   // NOP
</code>
Nach dem Login kopieren

使用的代码:

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type CategoryProduct struct {
    gorm.Model
    Title       string `json:"title" gorm:"not null"`
    Description string `json:"description"`
}

type CreateCategoryProduct struct {
    gorm.Model
    Title       string `json:"title" binding:"required"`
    Description string `json:"description" binding:"required"`
}

// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
type PriceYearProduct struct {
    gorm.Model
    Price       float64 `json:"price" gorm:"not null"`
    Description string  `json:"description"`
}

type CreatePriceYearProduct struct {
    gorm.Model
    Price       float64 `json:"price" binding:"required"`
    Description string  `json:"description" binding:"required"`
}

// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
type PriceMounthProduct struct {
    gorm.Model
    Price       float64 `json:"price" gorm:"not null"`
    Description string  `json:"description"`
}

type CreatePriceMounthProduct struct {
    gorm.Model
    Price       float64 `json:"price" binding:"required"`
    Description string  `json:"description" binding:"required"`
}

// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
type Product struct {
    gorm.Model
    Name               string             `json:"name" gorm:"not null"`
    Description        string             `json:"description" gorm:"not null"`
    PriceMounthProduct PriceMounthProduct `json:"pricemounth"`
    PriceYearProduct   PriceYearProduct   `json:"priceyear"`
    CategoryProduct    CategoryProduct    `json:"category"`
}

type CreateProduct struct {
    gorm.Model
    Name               string             `json:"name" binding:"required"`
    Description        string             `json:"description" binding:"required"`
    PriceMounthProduct PriceMounthProduct `json:"pricemounth" binding:"required"`
    PriceYearProduct   PriceYearProduct   `json:"priceyear" binding:"required"`
    CategoryProduct    CategoryProduct    `json:"category" binding:"required"`
}

var DB *gorm.DB

func ConnectDatabase() {

    database, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})

    if err != nil {
        panic("Failed to connect to database!")
    }
    // For the product and dependancies of them
    err = database.AutoMigrate(&CategoryProduct{}, &PriceYearProduct{}, &PriceMounthProduct{})
    if err != nil {
        return
    }
    err = database.AutoMigrate(&Product{})
    if err != nil {
        return
    }

    DB = database
}

// POST /v1/products
// Create a product
func CreatingProduct(c *gin.Context) {
    // Validate input
    var input CreateProduct
    if err := c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    data := Product{
        Name:               input.Name,
        Description:        input.Description,
        PriceYearProduct:   input.PriceYearProduct,
        PriceMounthProduct: input.PriceMounthProduct,
        CategoryProduct:    input.CategoryProduct,
    }
    DB.Create(&data)

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

}

func Routes() {
    var router = gin.Default()

    v1 := router.Group("/v1")
    {
        //Product CRUD
        product := v1.Group("/product")
        product.POST("/products", CreatingProduct)

    }

    err := router.Run(":8080")
    if err != nil {
        return
    }
}

func main() {
    ConnectDatabase()
    Routes()

}
Nach dem Login kopieren

以及用于发布一些数据的curl命令:

curl http://localhost:8080/v1/product/products --request "POST" --header "Content-Type: application/json" --data @file.json
Nach dem Login kopieren

file.json 的内容:

<code>{
    "name": "airplane simulation",
    "description": "airplane simulation for everybody, childrens to adults.",
    "priceyear": {
      "price": 44.99,
      "description": "pay for a year to access on irplane simulation for everybody, childrens to adults."
    },
    "pricemounth": {
      "price": 4.99,
      "description": "pay for a mounth to access on irplane simulation for everybody, childrens to adults."
    },
    "category": {
      "title": "Airplane",
      "description": "Information cataegorized on airplane."
    }
}
</code>
Nach dem Login kopieren

我查看了官方文档,但没有更多信息...... 尝试使用创建时的变量进行调试,但一切似乎都很好......

解决方法

运行代码出现错误

[error] invalid field found for struct
 main.Product's field PriceMounthProduct: 
define a valid foreign key for 
relations or implement the Valuer/Scanner interface
Nach dem Login kopieren

gin日志前第一行的错误信息,可能你错过了。

所以修复它,在 Product 结构中添加正确的 foreignkey gorm 标签 就可以了。

<code>
type Product struct {
    gorm.Model
    Name               string             `json:"name" gorm:"not null"`
    Description        string             `json:"description" gorm:"not null"`
    PriceMounthProduct PriceMounthProduct `json:"pricemounth" gorm:"foreignkey:ID"`
    PriceYearProduct   PriceYearProduct   `json:"priceyear" gorm:"foreignkey:ID"`
    CategoryProduct    CategoryProduct    `json:"category" gorm:"foreignkey:ID"`
}
</code>
Nach dem Login kopieren

然后运行

curl http://localhost:8080/v1/product/products --request "POST" --header "Content-Type: application/json" --data @info.json
Nach dem Login kopieren

得到了

<code>{"data":{"ID":1,"CreatedAt":"2023-11-02T13:37:24.052228+08:00","UpdatedAt":"2023-11-02T13:37:24.052228+08:00","DeletedAt":null,"name":"airplane simulation","description":"airplane simulation for everybody, childrens to adults.","pricemounth":{"ID":1,"CreatedAt":"2023-11-02T13:37:24.054792+08:00","UpdatedAt":"2023-11-02T13:37:24.054792+08:00","DeletedAt":null,"price":4.99,"description":"pay for a mounth to access on irplane simulation for everybody, childrens to adults."},"priceyear":{"ID":1,"CreatedAt":"2023-11-02T13:37:24.056352+08:00","UpdatedAt":"2023-11-02T13:37:24.056352+08:00","DeletedAt":null,"price":44.99,"description":"pay for a year to access on irplane simulation for everybody, childrens to adults."},"category":{"ID":1,"CreatedAt":"2023-11-02T13:37:24.056585+08:00","UpdatedAt":"2023-11-02T13:37:24.056585+08:00","DeletedAt":null,"title":"Airplane","description":"Information cataegorized on airplane."}}}% 
</code>
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonGolang GORM und Gin können kein Objekt mit Assoziation erstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!