Issue with Storing Array of Strings in Spanner Using GORM
Opened this issue · 1 comments
fabianedl777 commented
- What you're trying to do
I'm trying to store a set of values in a column of type array string in Spanner using GORM, but I'm encountering an error.
- What code you've already tried
type NewEntity struct {
Field1 int64 `gorm:"primaryKey;autoIncrement:false;column:picture_key"`
Field2 []string `gorm:"type:ARRAY<STRING(MAX)>;column:models"`
Field3 time.Time `gorm:"column:updated_at"`
}
dbEntity := model.NewEntity(p)
err := db.Create(dbEntity).Error
if err != nil {
panic(err)
}
- Any error messages you're getting
spanner: code = \"InvalidArgument\", desc = \"Value has type STRUCT<STRING, STRING, STRING, ...> which cannot be inserted into column Field2, which has type ARRAY<STRING> [at 1:168]\\n...Field3`) VALUES (@p1,(@p2,@p3,@p4,@p5,@p6,@p7,@..
for this reason i created a next custom type
package model
import (
"fmt"
"cloud.google.com/go/spanner"
"database/sql/driver"
)
type ArrayString []string
func (as *ArrayString) Scan(value interface{}) error {
if value == nil {
return nil
}
spannerArray, ok := value.([]spanner.NullString)
if !ok {
return fmt.Errorf("failed to scan ArrayString: unexpected error")
}
*as = make([]string, len(spannerArray))
for i, v := range spannerArray {
if v.Valid {
(*as)[i] = v.StringVal
}
}
return nil
}
func (as ArrayString) Value() (driver.Value, error) {
return []string(as), nil
}
func (ArrayString) GormDataType() string {
return "ARRAY<STRING(MAX)>"
}
type NewEntity struct {
Field1 int64 `gorm:"primaryKey;autoIncrement:false;column:picture_key"`
Field2 ArrayString `gorm:"type:ARRAY<STRING(MAX)>;column:models"`
Field3 time.Time `gorm:"column:updated_at"`
}
dbEntity := model.NewEntity(p)
err := db.Create(dbEntity).Error
if err != nil {
panic(err)
}
However, after the changes made in the ticket, my previous solution no longer works. I'm not sure if my solution was the correct way to address the problem, but it was working previously. now i have this error
sql: converting argument $2 type: spanner: code = \"InvalidArgument\", desc = \"unsupported value type: model.ArrayString\"
Thank you very much for your help!
pdarulewski commented
I managed to make it work - instead of returning []float64
in my case, it worked with []spanner.NullFloat64
.
But I would say this should work with regular types like []float64
too.