go - 由于 "panic: reflect.StructOf: duplicate field"无法运行 Go 服务器

标签 go go-gorm

我正在尝试创建一个包含 3 个主要模型和 3 个 Controller 的后端 API,但每当我运行 go run main.go 时,我都会遇到麻烦,因为它会给出以下错误消息:我有一个重复的 DeveloperID 字段:

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

panic: reflect.StructOf: duplicate field DeveloperID

goroutine 1 [running]:
reflect.StructOf({0xc0003ee000, 0x3, 0xc00039e980})
        /snap/go/8627/src/reflect/type.go:2597 +0x1d45
gorm.io/gorm/schema.(*Schema).buildMany2ManyRelation(0xc00000c3c0, 0xc0001fcab0, 0xc0003cb6c0, {0x9a9922, 0xc0003b7470})
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="35525a47587543041b07071b06" rel="noreferrer noopener nofollow">[email protected]</a>/schema/relationship.go:270 +0xc25
gorm.io/gorm/schema.(*Schema).parseRelation(0xc00000c3c0, 0xc0003cb6c0)
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="abccc4d9c6ebdd9a8599998598" rel="noreferrer noopener nofollow">[email protected]</a>/schema/relationship.go:79 +0x31f
gorm.io/gorm/schema.ParseWithSpecialTableName({0x9ab3c0, 0xc0000de580}, 0xc0003b74d0, {0xb35250, 0xc0003b7470}, {0x0, 0x0})
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5c3b332e311c2a6d726e6e726f" rel="noreferrer noopener nofollow">[email protected]</a>/schema/schema.go:275 +0x2105
gorm.io/gorm.(*Statement).ParseWithSpecialTableName(0xc0003ca540, {0x9ab3c0, 0xc0000de580}, {0x0, 0x203000})
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0a6d6578674a7c3b2438382439" rel="noreferrer noopener nofollow">[email protected]</a>/statement.go:463 +0x67
gorm.io/gorm.(*Statement).Parse(...)
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="42252d302f0234736c70706c71" rel="noreferrer noopener nofollow">[email protected]</a>/statement.go:459
gorm.io/gorm/migrator.Migrator.ReorderModels.func1({0x9ab3c0, 0xc0000de580}, 0x1)
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3a5d5548577a4c0b1408081409" rel="noreferrer noopener nofollow">[email protected]</a>/migrator/migrator.go:702 +0x179
gorm.io/gorm/migrator.Migrator.ReorderModels({{0x60, 0xc0003b77a0, {0xb37360, 0xc0003b77d0}}}, {0xc0003d8460, 0x1, 0xa51940}, 0x1)
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cea9a1bca38eb8ffe0fcfce0fd" rel="noreferrer noopener nofollow">[email protected]</a>/migrator/migrator.go:765 +0x630
gorm.io/gorm/migrator.Migrator.AutoMigrate({{0x0, 0xc0003b77a0, {0xb37360, 0xc0003b77d0}}}, {0xc0003d8460, 0x0, 0x0})
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1c7b736e715c6a2d322e2e322f" rel="noreferrer noopener nofollow">[email protected]</a>/migrator/migrator.go:90 +0x6d
gorm.io/gorm.(*DB).AutoMigrate(0xb371a8, {0xc0003d8460, 0x1, 0x1})
        /home/nero/go/pkg/mod/gorm.io/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="abccc4d9c6ebdd9a8599998598" rel="noreferrer noopener nofollow">[email protected]</a>/migrator.go:26 +0x43
SMS-Go/models.ConnectDatabase()
        /home/nero/go/src/SMS-Go/models/setup.go:17 +0x111
main.main()
        /home/nero/go/src/SMS-Go/main.go:13 +0x27
exit status 2

这是我的模型和正在读取的 Controller : trigger_controller.go:


/controllers/trigger_controller.go

package controllers

import (
    "SMS-Go/models"
    "net/http"
    "time"

    "github.com/gin-gonic/gin"
    uuid "github.com/nu7hatch/gouuid"
)

type MessageInput struct {
    TeamID  int    `json:"team_id" binding:"required"`
    Title   string `json:"title" binding:"required"`
    Content string `json:"content" binding:"required"`
}

// type Response struct {
//  TeamID string `json:"team_id"`
//  Sms    Sms    `json:"sms"`
//  Email  Email  `json:"email"`
// }
// type Sms struct {
//  ID      string   `json:"id"`
//  Mobiles []string `json:"mobiles"`
//  Content string   `json:"content"`
//  SentAt  string   `json:"sent_at"`
// }
// type Email struct {
//  ID      string   `json:"id"`
//  Emails  []string `json:"emails"`
//  Title   string   `json:"title"`
//  Content string   `json:"content"`
//  SentAt  string   `json:"sent_at"`
// }

func Notification(c *gin.Context) {
    var input MessageInput //input validation
    if err := c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    u1, err := uuid.NewV4()
    _ = err
    message := models.Message{TeamID: input.TeamID, Title: input.Title, Content: input.Content}
    models.DB.Create(&message)
    mob := models.DB.Raw(`SELECT "developers"."mobile" FROM "developers" INNER JOIN "developer_teams" ON "developers"."id" = "developer_teams"."developer_id" WHERE "developer_teams"."team_id"`)
    mail := models.DB.Raw(`SELECT "developers"."email" FROM "developers" INNER JOIN "developer_teams" ON "developers"."id" = "developer_teams"."developer_id" WHERE "developer_teams"."team_id"`)

    c.JSON(http.StatusOK, gin.H{
        "team_id": input.TeamID,
        "sms": gin.H{
            "id":      u1,
            "mobiles": mob,
            "content": input.Content,
            "sent_at": time.Now(),
        },
        "email": gin.H{
            "id":      u1,
            "emails":  mail,
            "title":   input.Title,
            "content": input.Content,
            "sent_at": time.Now(),
        },
    },
    )

}

team.go:

/models/team.go

package models

import "gorm.io/gorm"

type Team struct {
    gorm.Model
    ID       uint   `json:"id" gorm:"primary_key"`
    Name     string `json:"name"`
    Dept     string `json:"dept_name"`
    Messages []Message
}

developer.go:

/models/developer.go

package models

import "gorm.io/gorm"

type Developer struct {
    gorm.Model
    ID         uint        `json:"id" gorm:"primary_key"`
    Full_name  string      `json:"full_name"`
    Email      string      `json:"email"`
    Mobile     string      `json:"mobile"`
    Developers []Developer `gorm:"many2many:developer_teams"`
}

message.go:

/models/message.go

package models

import "gorm.io/gorm"

type Message struct {
    gorm.Model
    ID      uint   `json:"id" gorm:"primary_key"`
    TeamID  int    `json:"team_id"`
    Title   string `json:"title"`
    Content string `json:"content"`
    Team    Team
}

我试图做到这一点,当您在 trigger_notification 中输入 JSON 形式的输入字段时,它会发回一个 JSON 响应,该响应通过移动设备显示特定团队下的所有开发人员和电子邮件对象。 响应应如下所示:

{
    team_id: "team_id",
    sms: {
        id: "ARANDOMID",
        mobiles: ["numer1","number2"]
        content: "the content of this message",
        sent_at: "18:54:34 IST 2021"
    },
    email: {
        id: "ARANDOMID",
        emails: ["<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="badfd7dbd3d68bfadfd7dbd3d694d9d5d7" rel="noreferrer noopener nofollow">[email protected]</a>", "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7f1a121e16134d3f1a121e1613511c1012" rel="noreferrer noopener nofollow">[email protected]</a>"]
        title: "Used in emails for title",
        content: "the content of this message",
        sent_at: "18:54:34 IST 2021"
    }

setup.go:

package models

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

var DB *gorm.DB

func ConnectDatabase() {
    database, err := gorm.Open(sqlite.Open("sms-go.db"), &gorm.Config{})

    if err != nil {
        panic("Failure to connect to database")
    }

    database.AutoMigrate(&Developer{})
    database.AutoMigrate(&Message{})
    database.AutoMigrate(&Team{})

    DB = database
}

最佳答案

对于自引用多对多关系,您需要使用与模型名称不同的字段名称,例如:

type Developer struct {
    gorm.Model
    ID        uint        `json:"id" gorm:"primary_key"`
    Full_name string      `json:"full_name"`
    Email     string      `json:"email"`
    Mobile    string      `json:"mobile"`

    // Change `Developers []Developer` to:
    DevTeam []Developer   `gorm:"many2many:developer_teams"`
}

参见gorm.io docs: Self-Referential Many2Many .

关于go - 由于 "panic: reflect.StructOf: duplicate field"无法运行 Go 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69985721/

相关文章:

go - 为什么 Golang GORM Hook BeforeUpdate,AfterUpdate 不触发?

Golang 的 GORM 不向 "has many"关系添加关联

json - 根据golang中的条件执行自解码方法或默认解码方法

go - 退出工作池实现中的 channel

sql - Gorm 在多对多插入中添加多个 slice

go - 使用 Gorm 检索有很多问题

sql - Golang 数据库管理器 api 概念,类型断言错误

types - go中某个值的动态类型是什么意思?

go - 如何 "bridge"writer 和 reader in go

unit-testing - 如何在 go 中实现 CLI 命令的单元测试