-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Spanner: Support Custom Marsheling and Unmarsheling #854
Comments
First, I'm not sure if this is something we want to support. If we do, however, So maybe we could test if a type implements |
@olavloite WDYT about this issue? Is this reasonable, or do you think it's out of scope? |
It's a nice-to-have, and I can understand the wish considering we already support automatically converting a row to a struct and a struct to a row (for updates and inserts). Limiting that process to purely copying data directly from one column to a field with the exact same type is quite limiting, and allowing some customization of that mapping process is reasonable. I would however take a slightly more generic approach and allow any valid Spanner data type to be encoded and decoded to/from any Go data type, and not limit it to That would also enable automatic encoding and decoding of for example decimal values, for which Spanner does not have a native data type. The Spanner documentation recommends encoding decimal values in either So we would get two interfaces approximately like this: type SpannerEncoder interface {
EncodeSpanner() (interface{}, error)
}
type SpannerDecoder interface {
DecodeSpanner(input interface{}) error
} |
@olavloite, I am investigating this issue now. I tried the following example: package main
import (
"context"
"log"
"time"
"cloud.google.com/go/spanner"
)
type customField struct {
Prefix string
Suffix string
}
type dbProductInfo struct {
ProductID int64 `spanner:"ProductID"`
UpdateDate time.Time `spanner:"UpdateDate"`
Data customField `spanner:"Data"`
}
func main() {
ctx := context.Background()
client, err := spanner.NewClient(ctx, "DB_PATH")
if err != nil {
log.Fatal(err)
}
defer client.Close()
d := dbProductInfo{
ProductID: 1234,
UpdateDate: time.Now(),
Data: customField{"prefix", "suffix"},
}
m, err := spanner.InsertStruct("ProductInfo", &d)
if err != nil {
log.Fatalf("err: %v", err)
}
ms := []*spanner.Mutation{m}
_, err = client.Apply(ctx, ms)
if err != nil {
log.Fatalf("err: %v", err)
}
} But it throws an error: google-cloud-go/spanner/value.go Lines 2665 to 2666 in e143982
It can support custom base types, e.g., once I changed to: type customField string It works fine. How can your proposed interfaces apply here? I guess we expect |
Yes, that is the basic idea, and that could also apply to custom structs. So if a struct implements the In the initial example of this issue the struct is encoded to a |
It would be great to have the possibility to have custom un-/marsheling for custom types support a la JSON de-&encoder or CSV de-&encoder:
Example:
DDL:
The text was updated successfully, but these errors were encountered: