Как преобразовать строку в sqlx.types.JSONText?

Я использую 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"}, чтобы сохранить как jsonb в postgres:

| id | quantity | attributes              |
|----|----------|-------------------------|
| 1  | 5        | {"target": "localhost"}|

Что я делаю не так?


Изменить: добавить образец мутации.

Это пример мутации:

mutation itemCreate {
  itemCreate(input: {
    quantity: 5,
    attributes: "{\"target\": \"localhost\"}"
  })
}

Изменить: добавить запрос sqlx.

Запрос для вставки:

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
}

1 ответ

Решение

Если v содержит буквальный json либо в []byte или же string тогда нет необходимости в 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
}
Другие вопросы по тегам