gorm: json of json不起作用

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

gorm: json of json not work

问题

{
"id": 1,
"data": {
"1": 2
}
}
结构定义:

type Item struct {
id int json:"id"
data interface{} json:"data"
}

我需要解析来自HTTP POST的有效负载,所以我在data字段上使用了interface{}json.Unmarshal()成功了,但是在调用db.Create(item)时,gorm产生了错误:

(sql: converting Exec argument #5's type: unsupported type map[string]interface {}, a map)

相反,如果我将interface{}更改为string,调用json.Unmarshal()来解析JSON POST有效负载会产生错误。

unmarshal类型错误:expected=string,got=object

基本上,一个需要interface{},一个需要string

有人遇到过这个问题吗?

英文:

Sample:

{
  "id": 1
  "data": {"1": 2}
}

Struct definition:

type Item struct {
  id int `json:"id"`
  data interface{} `json:"data"`
}

I need to parse the payload from a http post, so I used interface{} for data, json.Unmarshal() is successful, but gorm produces error while calling db.Create(item):

(sql: converting Exec argument #5's type: unsupported type map[string]interface {}, a map)

Instead, I change from interface{} to string, calling json.Unmarshal() to parse json POST payload produces error.

unmarshal type error: expected=string, got=object

Basically, one requires interface{}, one requires string.

Anyone encountered this?

答案1

得分: 1

解决方案是定义一个自定义类型,实现 sql.Valuersql.Scannerjson.Marshalerjson.Unmarshaler 接口。以下是我实现的示例代码:

type Data string

func (t *Data) MarshalJSON() ([]byte, error) {
    return []byte(*t), nil
}

func (t *Data) UnmarshalJSON(data []byte) error {
    *t = Data(data)
    return nil
}

func (t Data) Value() (driver.Value, error) {
    return string(t), nil
}

func (t *Data) Scan(src interface{}) error {
    s, ok := src.([]byte)
    if !ok {
        return nil
    }
    *t = Data(s)
    return nil
}

// Data 实现以下接口,以满足 json 解析器和 sql 解析器的要求
var _ json.Marshaler = (*Data)(nil)
var _ json.Unmarshaler = (*Data)(nil)
var _ sql.Scanner = (*Data)(nil)
var _ driver.Valuer = (*Data)(nil)

以上代码定义了一个名为 Data 的自定义类型,并实现了相应的接口方法,以满足 JSON 解析器和 SQL 解析器的要求。

英文:

The solution is defining a custom type that implements sql.Valuer, sql.Scanner, json.Marshaler and json.Unmarshaler interfaces. Sample of my implementation:

<!-- language: go -->

type Data string

func (t *Data) MarshalJSON() ([]byte, error) {
    return []byte(*t), nil
}

func (t *Data) UnmarshalJSON(data []byte) error {
    *t = Data(data)
    return nil
}

func (t Data) Value() (driver.Value, error) {
    return string(t), nil
}

func (t *Data) Scan(src interface{}) error {
    s, ok := src.([]byte)
    if !ok {
        return nil
    }
    *t = Data(s)
    return nil
}

// Data implements the below interfaces to satisfy both
// json parser and sql parser
var _ json.Marshaler = (*Data)(nil)
var _ json.Unmarshaler = (*Data)(nil)
var _ sql.Scanner = (*Data)(nil)
var _ driver.Valuer = (*Data)(nil)

huangapple
  • 本文由 发表于 2016年12月14日 23:17:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/41146050.html
匿名

发表评论

匿名网友

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

确定