2016-12-14 9 views
0

Пример:Горм: JSON из JSON не работает

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

Struct определение:

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

мне нужно разобрать полезную нагрузку от HTTP POST, так что я использовал interface{} для data, json.Unmarshal() успешно , но gorm производит ошибку при вызове db.Create(item):

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

Вместо этого я изменяю от interface{} до string, вызывая json.Unmarshal() для разбора полезной нагрузки json POST.

unmarshal type error: expected=string, got=object 

В принципе, один требует interface{}, один требует string.

Кто-нибудь сталкивался с этим?

+0

Прежде всего, ** как это не работает? ** Что происходит? Во-вторых, я не эксперт Go, но разве не было бы смысла, что вторая аннотация читала 'json:" data "'? – Jules

+0

Спасибо за предложение. –

+0

Если это работает с уже существующей базой данных, есть ли вероятность возникновения конфликта типа между полем данных и соответствующим полем базы данных? – Jules

ответ

0

Решение определяет нестандартный тип, который реализует интерфейсы 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 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)