GORM 的自定义 Point 类型错误 - 恐慌:反射:在切片 Value 上调用 Reflect.Value.Field

问题描述 投票:0回答:1
我需要将 Point 类型存储在我的数据库中。

我阅读了

自定义类型的文档以及来自MySQL/MariaDB的扫描点类型的建议

然后我用

GormDataType

GormValue
Scan
 函数编写自定义类型 Point,但是当尝试从数据库获取数据时,我收到错误 
panic: reflect: call of reflect.Value.Field on slice Value

我能解决什么问题吗?

详情

    型号
package models // ...imports type User struct { gorm.Model Id uint64 `gorm:"primaryKey;autoIncrement:true"` Name string `gorm:"size:255;index:idx_name,unique"` Password string `gorm:"size:64"` CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time Walks []Walk `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL"` } type Walk struct { gorm.Model Id uint64 `gorm:"primaryKey;autoIncrement:true"` UserId uint64 Coords types.Point Altitude float64 CreatedAt time.Time }

package types // ...imports type Point struct { Latitude, Longitude float64 } func (p Point) GormDataType() string { return "point" } func (p Point) GormValue(ctx context.Context, db *gorm.DB) clause.Expr { return clause.Expr{ SQL: "ST_PointFromText(?)", Vars: []interface{}{fmt.Sprintf("POINT(%f %f)", p.Latitude, p.Longitude)}, } } func (p *Point) Scan(src interface{}) (err error) { switch src.(type) { case []byte: data, ok := src.([]byte) if !ok { return errors.New(fmt.Sprintf("(*Point).Scan: Error of scan source value of type %T", src)) } if len(data) != 25 { return errors.New(fmt.Sprintf("(*Point).Scan: Expected []bytes with length 25, got %d", len(data))) } var latitude, longitude float64 buf := bytes.NewReader(data[9:17]) err := binary.Read(buf, binary.LittleEndian, &latitude) if err != nil { return err } buf = bytes.NewReader(data[17:25]) err = binary.Read(buf, binary.LittleEndian, &longitude) if err != nil { return err } *p = Point{latitude, longitude} default: return errors.New(fmt.Sprintf("(*Point).Scan: Expected []byte for Point type, got %T", src)) } return nil }

    获取数据
db.Model(&models.User{}).Joins("Walks").First(&user, "users.name = ?", "***")
    
mysql go grails-orm point
1个回答
0
投票
问题解决了。点类型正确,但从数据库加载一对多数据是错误的。

要加载多对多关系,需要使用

Preload

 代替 
Joins
文档)。

示例。

更换

db.Model(&models.User{}).Joins("Walks").First(&user, "users.name = ?", "***")

db.Model(&models.User{}).Preload("Walks").First(&user, "users.name = ?", "***")
    
© www.soinside.com 2019 - 2024. All rights reserved.