Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with Storing Array of Strings in Spanner Using GORM #331

Open
fabianedl777 opened this issue Nov 26, 2024 · 1 comment
Open

Issue with Storing Array of Strings in Spanner Using GORM #331

fabianedl777 opened this issue Nov 26, 2024 · 1 comment
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue.

Comments

@fabianedl777
Copy link

fabianedl777 commented Nov 26, 2024

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

@fabianedl777 fabianedl777 added priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue. labels Nov 26, 2024
@pdarulewski
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: question Request for information or clarification. Not an issue.
Projects
None yet
Development

No branches or pull requests

2 participants