为了账号安全,请及时绑定邮箱和手机立即绑定

Unmarshal 从 postgresql 获取的对象的 Json 数组

Unmarshal 从 postgresql 获取的对象的 Json 数组

Go
翻阅古今 2023-07-31 16:30:45
我在 Postgres 中有一个 Jsonb 表Create Table Business(    id serial not null primary key,    id_category integer not null,    name varchar(50) not null,    owner varchar(200) not null,    coordinates jsonb not null,    reason varchar(300) not null,    foreign key(id_category) references Category(id));正如你所看到的,我将坐标存储为jsonb前任:Insert into Business(id_category, name, owner, coordinates, reason) values (1,'MyName','Owner', [{"latitude": 12.1268142, "longitude": -86.2754}]','Description')我提取数据并分配它的方式是这样的。type Business struct {    ID int `json:"id,omitempty"`    Name string `json:"name,omitempty"`    Owner string `json:"owner,omitempty"`    Category string `json:"category,omitempty"`    Departments []string `json:"departments,omitempty"`    Location []Coordinates `json:"location,omitempty"`    Reason string `json:"reason,omitempty"`}type Coordinates struct {    Latitude float64 `json:"latitude,omitempty"`    Longitude float64 `json:"longitude,omitempty"`}func (a Coordinates) Value() (driver.Value, error) {    return json.Marshal(a)}func (a *Coordinates) Scan(value []interface{}) error {    b, ok := value.([]byte)    if !ok {        return errors.New("type assertion to []byte failed")    }    return json.Unmarshal(b, &a)}然而,我不断收到这样的消息。sql:列索引 3 上的扫描错误,名称“坐标”:不支持的扫描,将 driver.Value 类型 []uint8 存储到类型 *models.Cooperatives 中谁能告诉我如何解决这个问题?检索对象的 json 数组并将其分配给 Business 内的坐标字段。
查看完整描述

2 回答

?
拉丁的传说

TA贡献1789条经验 获得超8个赞

1.

正如您从文档中看到的Scanner,要满足该接口,需要该方法

Scan(src interface{}) error

但你的*Coordinates类型实现了不同的方法

Scan(value []interface{}) error

类型interface{}[]interface{}是两个截然不同的东西。

2.

Scanner 接口必须在要作为参数传递给 的字段类型上实现rows.Scan。也就是说,您已经Scan在 上实现了您的方法*Coordinates,但 Location 字段的类型是[]Coordinates

同样,类型*Coordinates和类型[]Coordinates是两个非常不同的东西。


因此,解决方案是在正确的类型上正确实现接口。

请注意,由于 Go 不允许向未命名类型添加方法,并且[]Coordinates 未命名类型,因此您需要声明一个新类型,然后使用它来代替[]Coordinates.

type CoordinatesSlice []Coordinates


func (s *CoordinatesSlice) Scan(src interface{}) error {

    switch v := src.(type) {

    case []byte:

        return json.Unmarshal(v, s)

    case string:

        return json.Unmarshal([]byte(v), s)

    }

    return errors.New("type assertion failed")

}


// ...


type Business struct {

    // ...

    Location CoordinatesSlice `json:"location,omitempty"`

    // ...

}

笔记

如果业务位置始终只有对坐标作为 jsonb 对象存储到数据库中,并将类型Location从更改CoordinatesSliceCoordinates,相应地将Scanner实现从移动*CoordinatesSlice*Coordinates


查看完整回答
反对 回复 2023-07-31
?
三国纷争

TA贡献1804条经验 获得超7个赞

我知道这个解决方案确实没有优化,但这是唯一有效的方法。


基本上我必须获取 json,然后对 Location 属性进行解组。


var location string = ""


if err := json.Unmarshal([]byte(location), &business.Location); err != nil { panic(err) }



查看完整回答
反对 回复 2023-07-31
  • 2 回答
  • 0 关注
  • 72 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信