このページは?
map[string]interface{}
のデータをDatastoreに保存/取得したくなったので、その方法をメモとして残しておきます。
Datastoreにmap
型を保存する
Golangで、Datastoreに保存できるプロパティの型は以下にまとまっています。
https://cloud.google.com/appengine/docs/standard/go/datastore/entities
map
型を直接、Cloud Datastore保存させることはできません!
[]byte
型に変換することで、保存することができます。
⚠️注意点⚠️
[]byte
型は1MBまでしか保存することができません。
またインデックスさせることもできません。
Value type Go type(s) Sort order Notes Byte slice (long) []byte None Up to 1 megabyte
Not indexed
例
type User struct {
ID string
Claims map[string]interface{} `datastore:"-"`
ClaimsBinary []byte
Name string `datastore:"-"`
}
PropertyLoadSaver
PropertyLoadSaver
を活用することで、読み込み時にmap
の値を取得したり、保存時にmap
→[]byte
に変換することができます。
func (u *User) Load(ps []datastore.Property) error {
if err := load(u, ps); err != nil {
return err
}
if err := json.Unmarshal(u.ClaimsBinary, &u.Claims); err != nil {
return err
}
u.Name = u.Claims["name"].(string)
return nil
}
func (u *User) Save() ([]datastore.Property, error) {
binary, err := json.Marshal(u.Claims)
if err != nil {
return nil, err
}
u.ClaimsBinary = binary
return save(u)
}
参考
- https://github.com/GoogleCloudPlatform/google-cloud-go/issues/223