2014-09-13 2 views
3

Так что у меня-структуру, как этотСведение вложенными структурами приводит к ломтиком ломтиков

type Bus struct { 
    Number   string 
    Name   string 
    DirectStations []Station // Station is another struct 
    ReverseStations []Station 
} 

и я пытаюсь сохранить экземпляр этого к Datastore:

key := datastore.NewKey(c, "Bus", bus.Number, 0, nil) 
_, err := datastore.Put(c, key, &bus) 

но I Получение ошибки

datastore: 
flattening nested structs leads to a slice of slices: 
field "DirectStations" 

Как решить эту проблему?

Edit:

Оказывается, вы не можете иметь кусочек структуры, где эта структура содержит другие кусочки.

+0

Может ли http://stackoverflow.com/q/20710802/6309 помочь? – VonC

+0

Не совсем. Я видел этот пост, но на самом деле я его не понимаю. – mihai

+1

Часть, заявляющая, что «пакет хранилища данных не поддерживает два слоя срезов», довольно ясен. Что делать, это менее понятно и привлекать внимание к тому, что делает appengine/datastore. – VonC

ответ

3

Просто кодировать эту структуру в JSON (в байтах) и хранить JSON в хранилище данных

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

+0

Я отказался от этого некоторое время назад. Но, да, я, кажется, помню, что я сделал то, что вы предложили. Все это сработало для написания байтов в хранилище данных. Но чтение байтов назад просто вернуло пустую последовательность. Я отказался от Go + Google AppEngine, пытаясь обойти эти проблемы безуспешно. – mihai

+0

Привет, я отредактировал ответ. – Minty

0

Другой вариант для тех, кто приходит сюда, чтобы просто не храните кусочек структур в качестве ребенка в хранилище данных, затем просто загружайте их отдельно, когда вы загружаете obj

Что-то вроде:

type Parent struct { 
    Id  int64  `json:"id"` 
    Nested []Child `json:"children" datastore:"-"` 
    ... 
} 

type Child struct { 
    Id  int64  `json:"id"` 
    ParentId int64  `json:"parent_id"` 
    ... 
} 

Затем, когда вы хотите загрузить родитель, давайте предположим, что этот код находится в служебном модуле и у Вас есть удобный модуль данных на самом деле вытащить вещи из хранилища данных (которые вы, вероятно, должны)

func LoadParentWithNested(parent_id int64) (Parent, error){ 
    parent := data.GetParent(parent_id) 
    parent.Nested := data.LoadNested(parent.Id) 

    return parent 
} 

Очевидно, что вы хотите, проверку ошибок и все, но это вроде того, что вы должны сделать для сложных вложенных структур.

Смежные вопросы