googleapis/go-sql-spanner

Issue with Storing Array of Strings in Spanner Using GORM

Opened this issue · 1 comments

  • 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!

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.