I am trying to get an array of UUID
from a PostgreSQL DB, this gives the following error:
sql: Scan error on column index 0: unsupported Scan, storing driver.Value type []uint8 into type *[]string
Fetching a single UUID
is no problem, but when it is an array
, the Scan
function infers the type of the elements as uint8
.
Is there a workaround / solution for this? Or should I rethink my DB?
Code :
func FetchListIdsForUser(id string, db *sql.DB) ([]string, error) {
// where the results will be stored
var (
lists []string
)
// statement prep
stmt, err := db.Prepare("select lists from users where object_id = $1")
if err != nil {
formattedError := er.New("FetchListIdsForUser SQL Select: " + err.Error())
log.Println(formattedError)
return nil,formattedError
}
defer stmt.Close()
// query happening
rows, err := stmt.Query(id)
if err != nil {
formattedError := er.New("FetchListIdsForUser SQL Query: " + err.Error())
log.Println(formattedError)
return nil,formattedError
}
defer rows.Close()
// for each row
for rows.Next() {
// scan : this is where the error happens.
err := rows.Scan(&lists)
if err != nil {
formattedError := er.New("FetchListIdsForUser SQL Scan: " + err.Error())
log.Println(formattedError)
return nil,formattedError
}
return lists,nil
}
err = rows.Err()
if err != nil {
formattedError := er.New("FetchListIdsForUser: " + id + " Does Not Exist")
log.Println(formattedError)
return nil,formattedError
}
return nil,er.New("FetchListIdsForUser: " + id + " Does Not Exist")
}
Your code can be simplified a lot:
func FetchListIdsForUser(id string, db *sql.DB) ([]string, error) {
rows, err := db.Query("SELECT unnest(lists) FROM users WHERE object_id = $1", id)
if err != nil {
formattedError := errors.New("FetchListIdsForUser SQL Query: " + err.Error())
return nil, formattedError
}
defer rows.Close()
var lists []string
var list string
for rows.Next() {
// scan every item of the array and append it to lists
err := rows.Scan(&list)
if err != nil {
formattedError := errors.New("FetchListIdsForUser SQL Scan: " + err.Error())
return nil,formattedError
}
lists = append(lists, list)
}
if lists == nil {
// no rows returned
formattedError := errors.New("FetchListIdsForUser: " + id + " Does Not Exist")
return nil, formattedError
}
return lists, nil
}
db.Query()
will prepare (and cache) the statement for you. There's no need to do that manually.unnest(lists)
to the select statement. This will produce one row for every element in the array.lists
.Also, this driver supports scanning arrays out of the box.