英文:
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.Valuer、sql.Scanner、json.Marshaler 和 json.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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论