使用gorm映射表单遇到的疑问

正在学 gorm 库,就想着写一个社工库练手,⚠️这里仅仅用于学习。在使用 automigrate() 函数映射表单时出现如下错误,这是为什么呢?

Code

InitDB

package dao

import (
    "Hydra/config"
    "Hydra/model"
    "fmt"
    "gorm.io/gorm/schema"
    "log"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
)

var (
    _DB *gorm.DB
)

// InitDB Connect to DB
func InitDB() {
    cfg := config.GetConfig()
    username := cfg.GetString("db.username")
    password := cfg.GetString("db.password")
    host := cfg.GetString("db.host")
    port := cfg.GetInt("db.port")
    dbname := cfg.GetString("db.dbname")

    DSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", username, password, host, port, dbname)

    db, err := gorm.Open(mysql.New(mysql.Config{
        DSN: DSN,
    }), &gorm.Config{
        Logger: logger.Default.LogMode(logger.Info),
        NamingStrategy: schema.NamingStrategy{
            TablePrefix:   "hydra_",
            SingularTable: true,
        },
    })
    if err != nil {
        log.Println("connect mysql failed, err: ", err)
    }
    // Map the form to the database
    err = db.AutoMigrate(&model.Person{})
    if err != nil {
        log.Println("auto migrate err: ", err)
    }
    _DB = db
}

// DB return a *gorm.DB
func DB() *gorm.DB {
    return _DB
}

Person model

package model

import "gorm.io/gorm"
// Person base structure describe person's base info.
type Person struct {
    *gorm.Model
    *Notes
    Name       string `gorm:"column:name" json:"name"`
    Gender     string `gorm:"column:gender" json:"gender"`
    Birth      string `gorm:"column:birth" json:"birth"`
    BirthLocal string `gorm:"column:birth_local" json:"birthLocal"`
    IDNumber   string `gorm:"column:id_number" json:"IDNumber"`
    BankCard   uint   `gorm:"column:bank_card" json:"bankCard"`
}

func (p Person) TableName() string {
    return "person"
}

Person 父 struct

package model

// Notes describe something else remarks
type Notes struct {
    Notes []string `gorm:"column:notes" json:"notes"`
}

func (n Notes) TableName() string {
    return "notes"
}

main.go

package main

import (
    "Hydra/config"
    "Hydra/dao"
    "Hydra/router"

    "github.com/gin-gonic/gin"
)

func main() {
    // Init Config
    config.Config()

    // Init Database
    dao.InitDB()

    // Run server
    r := gin.Default()
    router.InitRouter(r)
    r.Run(":8080")
}

Err

tom:Hydra/ $ go run main.go                                                                                                                                                                                                  [14:07:36]

2023/02/10 14:07:43 /Users/tom/go/src/Hydra/dao/InitDB.go:52
[error] unsupported data type: &[]

2023/02/10 14:07:43 /Users/tom/go/src/Hydra/dao/InitDB.go:52
[error] failed to parse value &model.Person{Model:(*gorm.Model)(nil), Notes:(*model.Notes)(nil), Name:"", Gender:"", Birth:"", BirthLocal:"", IDNumber:"", BankCard:0x0}, got error unsupported data type: &[]

2023/02/10 14:07:43 /Users/tom/go/src/Hydra/dao/InitDB.go:52
[error] unsupported data type: &[]

2023/02/10 14:07:43 /Users/tom/go/src/Hydra/dao/InitDB.go:52
[error] unsupported data type: &[]

2023/02/10 14:07:43 /Users/tom/go/src/Hydra/dao/InitDB.go:52
[error] failed to parse value &model.Person{Model:(*gorm.Model)(nil), Notes:(*model.Notes)(nil), Name:"", Gender:"", Birth:"", BirthLocal:"", IDNumber:"", BankCard:0x0}, got error unsupported data type: &[]

2023/02/10 14:07:43 /Users/tom/go/src/Hydra/dao/InitDB.go:52
[error] unsupported data type: &[]
2023/02/10 14:07:43 auto migrate err:  unsupported data type: &[]
[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)
讨论数量: 5
giao哥

model.Person 写的有问题 notes 是什么

2年前 评论
giao哥 (作者) 2年前
Scrooge (楼主) 2年前

Notes没配置主键外键

2年前 评论

Person 中的 Notes 属于自定义类型的范畴,而 Notes 并没实现有自定义类型的 Scanner 和 Valuer 接口。所以会报错。可以查看 模型定义自定义数据类型 的相关内容。
自定义类型具体实现: model.go

// Person Person 类型定义
type Person struct {
    Notes Notes `gorm:"type:text[]"`
    // 省略其它字段
}

// Notes 自定义类型 需要实现 Scanner 和 Valuer 接口
type Notes []string

// Scan 实现 gorm 自定义类型的 Scanner 接口
func (n *Notes) Scan(value interface{}) error {
    if v, ok := value.(string); ok {
        *n = strings.Split(v, ",")
    }
    return errors.New("notes scan failed")
}

// Value 实现 gorm 自定义类型的 Valuer 接口
func (n Notes) Value() (driver.Value, error) {
    return strings.Join(n, ","), nil
}

该需求还可以使用表关联: model.go

// Person Person 类型定义
type Person struct {
    Notes      []*Notes
    // 省略其它字段
}

// Notes Notes 类型定义
type Notes struct {
    Notes    string `gorm:"column:notes" json:"notes"`
    PersonID uint
}
2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!