2
votes

I am writing a go program that reads values from mysql db and using rows.StructScan unmarshals it into go struct. But one of the fields returns a string which contains list of json objects. If the sqlx returns db results in []byte, StructScan should be able to unmarshal the detail string into detail struct but gives the following error: name "details": unsupported Scan, storing driver.Value type []uint8 into type *[]main.Details

import (
 _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"github.com/jmoiron/sqlx/reflectx"
 "encoding/json"
)

type Entity struct {
	ID          int           `db:"id"`
	Date        *int          `db:"date"`
	Details     []Details 	  `db:"details"`
}

type Details struct {
	Name        *string `json:"name"`
	Description *string `json:"description"`
	Code        string  `json:"code"`
}

//removed error handling for now 

dataQuery, args, err := sqlx.In(DATA_QUERY,IDs)
rows, err := db.Queryx(dataQuery, args...)
entityList := []*Entity{}

// 1. Doesn't works
for rows.Next() {
	entity := &Entity{}
	err := rows.StructScan(&entity)
	entityList = append(entityList, entity)
}

   // 2. works
  for rows.Next() {
        entity := &Entity{}
        var desc string
        err := rows.Scan(&entity.ID,&entity.Date,&desc)
        err = json.Unmarshal([]byte(desc), &entity.Details)
	    entityList = append(entityList, entity)
   }

//  db query result :
  id: 15
date: 1590177397603
details:[{"name":"Abc","description":"String","code":"CO1"},
			  {"name":"123","description":"Numbers","code":"CO2"}]

I don't want to go with the 2 method because say if I have many fields then Scan will make it look ugly and miss the advantage of StructScan. How should I otherwise carry out this?

1

1 Answers

0
votes

For a column with type JSON your struct field should be of type []byte there is no other way around this.

In this case, I would have used the mapscan() method, after scanning I would process the specific key by passing it to a function which unmarshalls the []byte to specific struct or map.

If you still want your result to be struct convert the map to a struct using some library. https://godoc.org/github.com/mitchellh/mapstructure