无法运行Go服务器,原因是“panic: reflect.StructOf: 重复字段”。

huangapple go评论115阅读模式
英文:

Unable to run Go server due to "panic: reflect.StructOf: duplicate field"

问题

我正在尝试创建一个包含3个主要模型和3个控制器的后端API,但是每当我运行go run main.go时遇到问题,因为它给我返回了一个错误消息,指出我有一个重复的DeveloperID字段:

  1. [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
  2. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
  3. - using env: export GIN_MODE=release
  4. - using code: gin.SetMode(gin.ReleaseMode)
  5. panic: reflect.StructOf: duplicate field DeveloperID
  6. goroutine 1 [running]:
  7. reflect.StructOf({0xc0003ee000, 0x3, 0xc00039e980})
  8. /snap/go/8627/src/reflect/type.go:2597 +0x1d45
  9. gorm.io/gorm/schema.(*Schema).buildMany2ManyRelation(0xc00000c3c0, 0xc0001fcab0, 0xc0003cb6c0, {0x9a9922, 0xc0003b7470})
  10. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/schema/relationship.go:270 +0xc25
  11. gorm.io/gorm/schema.(*Schema).parseRelation(0xc00000c3c0, 0xc0003cb6c0)
  12. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/schema/relationship.go:79 +0x31f
  13. gorm.io/gorm/schema.ParseWithSpecialTableName({0x9ab3c0, 0xc0000de580}, 0xc0003b74d0, {0xb35250, 0xc0003b7470}, {0x0, 0x0})
  14. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/schema/schema.go:275 +0x2105
  15. gorm.io/gorm.(*Statement).ParseWithSpecialTableName(0xc0003ca540, {0x9ab3c0, 0xc0000de580}, {0x0, 0x203000})
  16. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/statement.go:463 +0x67
  17. gorm.io/gorm.(*Statement).Parse(...)
  18. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/statement.go:459
  19. gorm.io/gorm/migrator.Migrator.ReorderModels.func1({0x9ab3c0, 0xc0000de580}, 0x1)
  20. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator/migrator.go:702 +0x179
  21. gorm.io/gorm/migrator.Migrator.ReorderModels({{0x60, 0xc0003b77a0, {0xb37360, 0xc0003b77d0}}}, {0xc0003d8460, 0x1, 0xa51940}, 0x1)
  22. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator/migrator.go:765 +0x630
  23. gorm.io/gorm/migrator.Migrator.AutoMigrate({{0x0, 0xc0003b77a0, {0xb37360, 0xc0003b77d0}}}, {0xc0003d8460, 0x0, 0x0})
  24. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator/migrator.go:90 +0x6d
  25. gorm.io/gorm.(*DB).AutoMigrate(0xb371a8, {0xc0003d8460, 0x1, 0x1})
  26. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator.go:26 +0x43
  27. SMS-Go/models.ConnectDatabase()
  28. /home/nero/go/src/SMS-Go/models/setup.go:17 +0x111
  29. main.main()
  30. /home/nero/go/src/SMS-Go/main.go:13 +0x27
  31. exit status 2

这是我的模型和正在被读取的控制器:
trigger_controller.go:

  1. /controllers/trigger_controller.go
  2. package controllers
  3. import (
  4. "SMS-Go/models"
  5. "net/http"
  6. "time"
  7. "github.com/gin-gonic/gin"
  8. uuid "github.com/nu7hatch/gouuid"
  9. )
  10. type MessageInput struct {
  11. TeamID int `json:"team_id" binding:"required"`
  12. Title string `json:"title" binding:"required"`
  13. Content string `json:"content" binding:"required"`
  14. }
  15. // type Response struct {
  16. // TeamID string `json:"team_id"`
  17. // Sms Sms `json:"sms"`
  18. // Email Email `json:"email"`
  19. // }
  20. // type Sms struct {
  21. // ID string `json:"id"`
  22. // Mobiles []string `json:"mobiles"`
  23. // Content string `json:"content"`
  24. // SentAt string `json:"sent_at"`
  25. // }
  26. // type Email struct {
  27. // ID string `json:"id"`
  28. // Emails []string `json:"emails"`
  29. // Title string `json:"title"`
  30. // Content string `json:"content"`
  31. // SentAt string `json:"sent_at"`
  32. // }
  33. func Notification(c *gin.Context) {
  34. var input MessageInput //input validation
  35. if err := c.ShouldBindJSON(&input); err != nil {
  36. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  37. return
  38. }
  39. u1, err := uuid.NewV4()
  40. _ = err
  41. message := models.Message{TeamID: input.TeamID, Title: input.Title, Content: input.Content}
  42. models.DB.Create(&message)
  43. 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"`)
  44. 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"`)
  45. c.JSON(http.StatusOK, gin.H{
  46. "team_id": input.TeamID,
  47. "sms": gin.H{
  48. "id": u1,
  49. "mobiles": mob,
  50. "content": input.Content,
  51. "sent_at": time.Now(),
  52. },
  53. "email": gin.H{
  54. "id": u1,
  55. "emails": mail,
  56. "title": input.Title,
  57. "content": input.Content,
  58. "sent_at": time.Now(),
  59. },
  60. },
  61. )
  62. }

team.go:

  1. /models/team.go
  2. package models
  3. import "gorm.io/gorm"
  4. type Team struct {
  5. gorm.Model
  6. ID uint `json:"id" gorm:"primary_key"`
  7. Name string `json:"name"`
  8. Dept string `json:"dept_name"`
  9. Messages []Message
  10. }

developer.go:

  1. /models/developer.go
  2. package models
  3. import "gorm.io/gorm"
  4. type Developer struct {
  5. gorm.Model
  6. ID uint `json:"id" gorm:"primary_key"`
  7. Full_name string `json:"full_name"`
  8. Email string `json:"email"`
  9. Mobile string `json:"mobile"`
  10. Developers []Developer `gorm:"many2many:developer_teams"`
  11. }

message.go:

  1. /models/message.go
  2. package models
  3. import "gorm.io/gorm"
  4. type Message struct {
  5. gorm.Model
  6. ID uint `json:"id" gorm:"primary_key"`
  7. TeamID int `json:"team_id"`
  8. Title string `json:"title"`
  9. Content string `json:"content"`
  10. Team Team
  11. }

我试图使得当您在trigger_notification中以JSON格式输入字段时,它会返回一个JSON响应,显示属于特定团队的所有开发人员,通过mobile和email对象。
响应应该类似于这样:

  1. {
  2. "team_id": "team_id",
  3. "sms": {
  4. "id": "ARANDOMID",
  5. "mobiles": ["numer1","number2"],
  6. "content": "the content of this message",
  7. "sent_at": "18:54:34 IST 2021"
  8. },
  9. "email": {
  10. "id": "ARANDOMID",
  11. "emails": ["email1@email.com", "email2@email.com"],
  12. "title": "Used in emails for title",
  13. "content": "the content of this message",
  14. "sent_at": "18:54:34 IST 2021"
  15. }
  16. }

setup.go:

  1. package models
  2. import (
  3. "gorm.io/driver/sqlite"
  4. "gorm.io/gorm"
  5. )
  6. var DB *gorm.DB
  7. func ConnectDatabase() {
  8. database, err := gorm.Open(sqlite.Open("sms-go.db"), &gorm.Config{})
  9. if err != nil {
  10. panic("Failure to connect to database")
  11. }
  12. database.AutoMigrate(&Developer{})
  13. database.AutoMigrate(&Message{})
  14. database.AutoMigrate(&Team{})
  15. DB = database
  16. }
英文:

I'm trying to create a backend API that contains 3 main models and 3 controllers but I'm running into trouble whenever I run go run main.go because it gives me this error message stating that I have a duplicate DeveloperID field:

  1. [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
  2. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
  3. - using env: export GIN_MODE=release
  4. - using code: gin.SetMode(gin.ReleaseMode)
  5. panic: reflect.StructOf: duplicate field DeveloperID
  6. goroutine 1 [running]:
  7. reflect.StructOf({0xc0003ee000, 0x3, 0xc00039e980})
  8. /snap/go/8627/src/reflect/type.go:2597 +0x1d45
  9. gorm.io/gorm/schema.(*Schema).buildMany2ManyRelation(0xc00000c3c0, 0xc0001fcab0, 0xc0003cb6c0, {0x9a9922, 0xc0003b7470})
  10. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/schema/relationship.go:270 +0xc25
  11. gorm.io/gorm/schema.(*Schema).parseRelation(0xc00000c3c0, 0xc0003cb6c0)
  12. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/schema/relationship.go:79 +0x31f
  13. gorm.io/gorm/schema.ParseWithSpecialTableName({0x9ab3c0, 0xc0000de580}, 0xc0003b74d0, {0xb35250, 0xc0003b7470}, {0x0, 0x0})
  14. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/schema/schema.go:275 +0x2105
  15. gorm.io/gorm.(*Statement).ParseWithSpecialTableName(0xc0003ca540, {0x9ab3c0, 0xc0000de580}, {0x0, 0x203000})
  16. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/statement.go:463 +0x67
  17. gorm.io/gorm.(*Statement).Parse(...)
  18. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/statement.go:459
  19. gorm.io/gorm/migrator.Migrator.ReorderModels.func1({0x9ab3c0, 0xc0000de580}, 0x1)
  20. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator/migrator.go:702 +0x179
  21. gorm.io/gorm/migrator.Migrator.ReorderModels({{0x60, 0xc0003b77a0, {0xb37360, 0xc0003b77d0}}}, {0xc0003d8460, 0x1, 0xa51940}, 0x1)
  22. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator/migrator.go:765 +0x630
  23. gorm.io/gorm/migrator.Migrator.AutoMigrate({{0x0, 0xc0003b77a0, {0xb37360, 0xc0003b77d0}}}, {0xc0003d8460, 0x0, 0x0})
  24. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator/migrator.go:90 +0x6d
  25. gorm.io/gorm.(*DB).AutoMigrate(0xb371a8, {0xc0003d8460, 0x1, 0x1})
  26. /home/nero/go/pkg/mod/gorm.io/gorm@v1.22.3/migrator.go:26 +0x43
  27. SMS-Go/models.ConnectDatabase()
  28. /home/nero/go/src/SMS-Go/models/setup.go:17 +0x111
  29. main.main()
  30. /home/nero/go/src/SMS-Go/main.go:13 +0x27
  31. exit status 2

Here are my models and the controller that is being read:
trigger_controller.go:

  1. /controllers/trigger_controller.go
  2. package controllers
  3. import (
  4. "SMS-Go/models"
  5. "net/http"
  6. "time"
  7. "github.com/gin-gonic/gin"
  8. uuid "github.com/nu7hatch/gouuid"
  9. )
  10. type MessageInput struct {
  11. TeamID int `json:"team_id" binding:"required"`
  12. Title string `json:"title" binding:"required"`
  13. Content string `json:"content" binding:"required"`
  14. }
  15. // type Response struct {
  16. // TeamID string `json:"team_id"`
  17. // Sms Sms `json:"sms"`
  18. // Email Email `json:"email"`
  19. // }
  20. // type Sms struct {
  21. // ID string `json:"id"`
  22. // Mobiles []string `json:"mobiles"`
  23. // Content string `json:"content"`
  24. // SentAt string `json:"sent_at"`
  25. // }
  26. // type Email struct {
  27. // ID string `json:"id"`
  28. // Emails []string `json:"emails"`
  29. // Title string `json:"title"`
  30. // Content string `json:"content"`
  31. // SentAt string `json:"sent_at"`
  32. // }
  33. func Notification(c *gin.Context) {
  34. var input MessageInput //input validation
  35. if err := c.ShouldBindJSON(&input); err != nil {
  36. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  37. return
  38. }
  39. u1, err := uuid.NewV4()
  40. _ = err
  41. message := models.Message{TeamID: input.TeamID, Title: input.Title, Content: input.Content}
  42. models.DB.Create(&message)
  43. 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"`)
  44. 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"`)
  45. c.JSON(http.StatusOK, gin.H{
  46. "team_id": input.TeamID,
  47. "sms": gin.H{
  48. "id": u1,
  49. "mobiles": mob,
  50. "content": input.Content,
  51. "sent_at": time.Now(),
  52. },
  53. "email": gin.H{
  54. "id": u1,
  55. "emails": mail,
  56. "title": input.Title,
  57. "content": input.Content,
  58. "sent_at": time.Now(),
  59. },
  60. },
  61. )
  62. }

team.go:

  1. /models/team.go
  2. package models
  3. import "gorm.io/gorm"
  4. type Team struct {
  5. gorm.Model
  6. ID uint `json:"id" gorm:"primary_key"`
  7. Name string `json:"name"`
  8. Dept string `json:"dept_name"`
  9. Messages []Message
  10. }

developer.go:

  1. /models/developer.go
  2. package models
  3. import "gorm.io/gorm"
  4. type Developer struct {
  5. gorm.Model
  6. ID uint `json:"id" gorm:"primary_key"`
  7. Full_name string `json:"full_name"`
  8. Email string `json:"email"`
  9. Mobile string `json:"mobile"`
  10. Developers []Developer `gorm:"many2many:developer_teams"`
  11. }

message.go:

  1. /models/message.go
  2. package models
  3. import "gorm.io/gorm"
  4. type Message struct {
  5. gorm.Model
  6. ID uint `json:"id" gorm:"primary_key"`
  7. TeamID int `json:"team_id"`
  8. Title string `json:"title"`
  9. Content string `json:"content"`
  10. Team Team
  11. }

I'm trying to make it such that when you enter the input fields as JSON in trigger_notification, it sends back a JSON response that shows all the developers that are under a specific team via the mobile and email objects.
The response should look something like this:

  1. {
  2. team_id: "team_id",
  3. sms: {
  4. id: "ARANDOMID",
  5. mobiles: ["numer1","number2"]
  6. content: "the content of this message",
  7. sent_at: "18:54:34 IST 2021"
  8. },
  9. email: {
  10. id: "ARANDOMID",
  11. emails: ["email1@email.com", "email2@email.com"]
  12. title: "Used in emails for title",
  13. content: "the content of this message",
  14. sent_at: "18:54:34 IST 2021"
  15. }

setup.go:

  1. package models
  2. import (
  3. "gorm.io/driver/sqlite"
  4. "gorm.io/gorm"
  5. )
  6. var DB *gorm.DB
  7. func ConnectDatabase() {
  8. database, err := gorm.Open(sqlite.Open("sms-go.db"), &gorm.Config{})
  9. if err != nil {
  10. panic("Failure to connect to database")
  11. }
  12. database.AutoMigrate(&Developer{})
  13. database.AutoMigrate(&Message{})
  14. database.AutoMigrate(&Team{})
  15. DB = database
  16. }

答案1

得分: 2

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

  1. type Developer struct {
  2. gorm.Model
  3. ID uint `json:"id" gorm:"primary_key"`
  4. Full_name string `json:"full_name"`
  5. Email string `json:"email"`
  6. Mobile string `json:"mobile"`
  7. // 将 `Developers []Developer` 更改为:
  8. DevTeam []Developer `gorm:"many2many:developer_teams"`
  9. }

请参阅 gorm.io 文档:自引用的多对多关系

英文:

For self-referential many2many relationship you need to use a field name that is different from the model's name, for example:

  1. type Developer struct {
  2. gorm.Model
  3. ID uint `json:"id" gorm:"primary_key"`
  4. Full_name string `json:"full_name"`
  5. Email string `json:"email"`
  6. Mobile string `json:"mobile"`
  7. // Change `Developers []Developer` to:
  8. DevTeam []Developer `gorm:"many2many:developer_teams"`
  9. }

See gorm.io docs: Self-Referential Many2Many.

huangapple
  • 本文由 发表于 2021年11月16日 16:12:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/69985721.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定