[] строка в jsonb с Gorm и postgres

У меня есть структура Go, которая содержит фрагмент строк, которые я хотел бы сохранить как объект jsonB в Postgres с GORM.

Я нашел решение, которое требует использования конкретного типа GORM (postgres.Jsonb), которого я бы хотел избежать.

Когда я пытаюсь запустить AutoMigrate со срезом в моей модели, он паникует и не запускается, хотя, когда я оборачиваю этот срез в структуру (что я в порядке), он будет работать без ошибок, но не создаст столбец в postgres.

type User struct {
        gorm.Model
        Data []string `sql:"type:"jsonb"; json:"data"`
} //Panics

type User struct {
        gorm.Model
        Data struct {
            NestedData []string
        } `sql:"type:"jsonb"; json:"data"`
} //Doesn't crash but doesn't create my column

Кто-нибудь мог манипулировать jsonb с помощью GORM без использования типа postgres.Jsonb в моделях?

См. также:  Невозможно развернуть Go в Oracle Cloud Function с помощью Cloud Shell
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 2
  1. Le G

    Определите новый тип:

    type Data map[string]interface{}
    

    И реализуйте на них интерфейсы Valuer и Scanner, что позволяет преобразовать поле в значение для базы данных и сканировать обратно в поле соответственно:

    // Value converts into []byte
    func (d Data) Value() (driver.Value, error) {
      j, err := json.Marshal(d)
      return j, err
    }
    
    // Scan puts the []byte back into Data
    func (d *Data) Scan(src interface{}) error {
      source, ok := src.([]byte)
      if !ok {
        return errors.New("Type assertion .([]byte) failed.")
      }
    
      var i interface{}
      if err := json.Unmarshal(source, &i); err != nil {
        return err
      }
    
      *d, ok = i.(map[string]interface{})
      if !ok {
        return errors.New("Type assertion .(map[string]interface{}) failed.")
      }
    
      return nil
    }
    

    Затем вы можете определить свое поле в своей модели следующим образом:

    type User struct {
            gorm.Model
            Data Data `type: jsonb not null default '{}'::jsonb`
    }
    

    Использование базового типа map[string]interface{} тоже неплохо, так как вы можете _7 _ / _ 8_ любой JSON в / из него.

    Это все еще работает? Я пробовал это и продолжаю получать panic: invalid sql type SomeMapType (map) У меня есть связанный с этим вопрос: stackoverflow.com/questions/63289749/ person Le G; 07.08.2020

  2. Le G

    Может быть:

    type DataJSONB []string
    
    func (dj DataJSONB) Value() (driver.Value, error) {
        return json.Marshal(dj)
    }
    
    func (dj *DataJSONB) Scan(value interface{}) error {
        b, ok := value.([]byte)
        if !ok {
            return fmt.Errorf("[]byte assertion failed")
        }
    
        return json.Unmarshal(b, dj)
    }
    
    // Your bit
    type User struct {
        gorm.Model
        Data DataJSONB `sql:"type:"jsonb"; json:"data"`
    }
    

    Я получаю эту ошибку: тег поля структуры sql:"type:"jsonb";json:"studs" несовместим с отражением.StructTag.Get: пары ключ: значение, не разделенные пробеламиstructtag person Le G; 08.11.2020

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: