问题描述
我正在使用gqlgen
,sqlx
和pgx
。尝试使用自定义标量以jonb类型存储在postgres数据库中。
// graph/model/item.go
type Attributes types.JSONText
// Marshal here
...
func (a *Attributes) UnmarshalGQL(v interface{}) error {
switch v := v.(type) {
case []byte:
log.Println(" >> unmarshal.byte:",v)
json.Unmarshal(v,&a)
return nil
case string:
log.Println(" >> unmarshal.string:",v) // >> unmarshal.string: {"target": "localhost"}
json.Unmarshal([]byte(v),a) // This gives `null` in postgres
log.Println(" >> unmarshal.aT:",reflect.TypeOf(a)) // >> unmarshal.aT: *model.Attributes
log.Println(" >> unmarshal.aV:",reflect.ValueOf(a)) // >> unmarshal.aV: &[]
return nil
default:
return errors.New(fmt.Sprintf("Unsupported type: %T",v))
}
}
a *Attributes
的期望结果应为{"target": "localhost"}
,以便在json中存储为jsonb:
| id | quantity | attributes |
|----|----------|-------------------------|
| 1 | 5 | {"target": "localhost"} |
我做错了什么?
编辑:添加样本突变。
这是样本突变:
mutation itemCreate {
itemCreate(input: {
quantity: 5,attributes: "{\"target\": \"localhost\"}"
})
}
要插入的查询:
func (d *ItemDb) ItemCreate(i *model.ItemInput) (*model.Item,error) {
log.Println(" >> i.Attributes:",i.Attributes) // >> i.Attributes: &[123 34 116 97 114 103 101 116 34 58 32 34 108 111 99 97 108 104 111 115 116 34 125]
item := &model.Item{}
if err := d.Get(item,`INSERT INTO items
(quantity,attributes)
VALUES ($1,$2)
RETURNING *`,i.Quantity,i.Attributes); err != nil {
return nil,err
}
return item,nil
}
解决方法
如果v
在[]byte
或string
中包含文字json,那么就不需要json.Unmarshal
了,只需要进行一次转换即可。
func (a *Attributes) UnmarshalGQL(v interface{}) error {
switch v := v.(type) {
case []byte:
*a = Attributes(v)
case string:
*a = Attributes(v)
default:
return errors.New(fmt.Sprintf("Unsupported type: %T",v))
}
return nil
}