Reputation: 4750
So I have a struct like this
type Bus struct {
Number string
Name string
DirectStations []Station // Station is another struct
ReverseStations []Station
}
and I'm trying to store an instance of this to the Datastore:
key := datastore.NewKey(c, "Bus", bus.Number, 0, nil)
_, err := datastore.Put(c, key, &bus)
but I'm getting the error
datastore:
flattening nested structs leads to a slice of slices:
field "DirectStations"
How does one solve this?
Edit:
Turns out you can't have a slice of struct, where that struct contains other slices.
Upvotes: 3
Views: 1772
Reputation: 6444
Another option for anyone that comes here is to just not store the slice of structures as a child in the datastore then just load them up separately when you're loading the obj
Something like:
type Parent struct {
Id int64 `json:"id"`
Nested []Child `json:"children" datastore:"-"`
...
}
type Child struct {
Id int64 `json:"id"`
ParentId int64 `json:"parent_id"`
...
}
Then when you want to load the parent, let's assume this code is in a service module and you've got a handy data module to actually pull stuff from the datastore (which you probably should)
func LoadParentWithNested(parent_id int64) (Parent, error){
parent := data.GetParent(parent_id)
parent.Nested := data.LoadNested(parent.Id)
return parent
}
Obviously you'll want error checking and all that, but this is kind of what you've got to do for complex nested structures.
Upvotes: 0
Reputation: 1251
Just encode this struct into json (bytes) and store the json in the datastore
EDIT / UPDATE
package main
import (
"encoding/json"
"fmt"
)
type Bus struct {
Number string `json:"number"`
Name string `json:"name"`
DirectStations []Station `json:"directstation"` // Station is another struct
ReverseStations []Station `json:"reversestation"`
}
type Station struct {
StationName string `json:"stationname"` // these tag names must match exactly how they look in json
}
func toJson(i interface{}) []byte {
data, err := json.Marshal(i)
if err != nil {
panic(err)
}
return data
}
func fromJson(v []byte, vv interface{}) {
json.Unmarshal(v, vv)
}
func main() {
bus := Bus{}
st := []Station{{"station1"}, {"station2"}}
bus.DirectStations = make([]Station, len(st))
for i, v := range st {
bus.DirectStations[i] = v
}
bus.Number = "2"
bus.Name = "BusName"
js := toJson(bus)
fmt.Println("JSON OUTPUT", string(js))
bus2 := Bus{}
fromJson(js, &bus2)
fmt.Printf("ORIGINAL STRUCT OUTPUT %#v", bus2)
}
http://play.golang.org/p/neAGgcAIZG
Upvotes: 3