I have a need to store a slice of slices in that Datastore. Since the Datastore doesn't support two levels of slices, I have encode the child slice as JSON and store it as a []byte
. I'm using the PropertyLoadSaver to accomplish this. The saving and loading works, but I've noticed that the saved entity has a empty []byte
for every parent element. After some investigation I discovered this is caused by the Variants.OptionsJSON
Property being referenced in the Save()
method and also an attribute of the struct.
So my question are:
- Is this a bug or am I doing something wrong?
- Is there a better way to accomplish this?
The one constraint I have is that I need to be able to query the entity by one of the "Variant" attributes, but not the "Variant.Options".
Thanks!
Example:
Given JSON
{
"variants": [{
"options": [
{
"name": "One",
"value": "one"
},{
"name": "Two",
"value": "two"
}]
}, {
"options": [
{
"name": "Three",
"value": "three"
},{
"name": "Four",
"value": "four"
}]
}]
}]
}
How it's stored in the datastore, notice the two empty '', ''
attributes at the end:
Entity Kind: Products
Entity Key: ahBkZXZ-c3RvcmVza2ktY29tchULEghQcm9kdWN0cxiAgICAgNDHCww
ID: 6507459568992256
Variants.OptionsJSON (list): `['[{"name":"One","value":"one"},{"name":"Two","value":"two"}]', '[{"name":"Three","value":"three"},{"name":"Four","value":"four"}]', '', '']`
model.go
import (
"appengine/datastore"
"encoding/json"
)
type Option struct {
Name string `json:"name"`
Value string `json:"value"`
}
type Variant struct {
OptionsJSON []byte `json:"-" datastore:"OptionsJSON"`
Options []Option `json:"options" datastore:"-"`
}
type Product struct {
Variants []Variant `json:"variants"`
}
func (x *Product) Load(c <-chan datastore.Property) error {
if err := datastore.LoadStruct(x, c); err != nil {
return err
}
for i, v := range x.Variants {
var opts []Option
json.Unmarshal(v.OptionsJSON, &opts)
x.Variants[i].Options = opts
}
return nil
}
func (x *Product) Save(c chan<- datastore.Property) error {
for _, v := range x.Variants {
b, _ := json.Marshal(v.Options)
c <- datastore.Property{
Name: "Variants.OptionsJSON",
Value: b,
NoIndex: true,
Multiple: true,
}
}
return datastore.SaveStruct(x, c)
}