由於性能方面的原因,我在Google的Google AppEngine項目中編寫了一個模塊,但需要能夠讀取數據存儲區中的某些實體。我寫出來的Go代碼,以便能夠讀取我在Python建出來的實體,但我收到以下錯誤:在Go中從Python項目加載數據存儲實體導致嵌套的結構片的切片錯誤
datastore: flattening nested structs leads to a slice of slices: field "Messages"
模型定義在Python:
class ModelB(ndb.Model):
msg_id = ndb.StringProperty(indexed=False)
cat_ids = ndb.StringProperty(repeated=True, indexed=False)
list_ids = ndb.StringProperty(repeated=True, indexed=False)
default_list_id_index = ndb.IntegerProperty(indexed=False)
class ModelA(ndb.Model):
date_join = ndb.DateTimeProperty(auto_now_add=True)
name = ndb.StringProperty()
owner_salutation = ndb.StringProperty(indexed=False)
owner_email_address = ndb.StringProperty()
logo_url = ndb.StringProperty(indexed=False)
...
messages = ndb.LocalStructuredProperty(ModelB, name='bm', repeated=True)
而且在圍棋:
type ModelB struct {
MessageID string `datastore:"msg_id,noindex"`
CategoryIDs []string `datastore:"cat_ids,noindex"`
ListIDs []string `datastore:"list_ids,noindex"`
DefaultListIDIndex int `datastore:"default_list_id_index,noindex"`
}
type ModelA struct {
DateJoin time.Time `datastore:"date_join,"`
Name string `datastore:"name,"`
OwnerSalutation string `datastore:"owner_salutation,noindex"`
OwnerEmailAddress string `datastore:"owner_email_address,"`
LogoURL string `datastore:"logo_url,noindex"`
Messages []ModelB `datastore:"bm,"`
}
有什麼我在這裏做錯了嗎?只是Go與Python模型定義之間的功能不兼容?
試圖解碼ModelB
重新定義ModelA
如下:
import pb "appengine_internal/datastore"
import proto "code.google.com/p/goprotobuf/proto"
type ModelA struct {
DateJoin time.Time `datastore:"date_join,"`
Name string `datastore:"name,"`
OwnerSalutation string `datastore:"owner_salutation,noindex"`
OwnerEmailAddress string `datastore:"owner_email_address,"`
LogoURL string `datastore:"logo_url,noindex"`
Messages []ModelB `datastore:"-"`
}
// Load is implemented for the PropertyLoaderSaver interface.
func (seller *ModelA) Load(c <-chan datastore.Property) error {
f := make(chan datastore.Property, 100)
for p := range c {
if p.Name == "bm" {
var val pb.EntityProto
err := proto.Unmarshal([]byte(p.Value.(string)), &val)
if err != nil {
return err
}
//TODO: Store result as a new ModelB
} else {
f <- p
}
}
close(f)
return datastore.LoadStruct(seller, f)
}
但我收到以下錯誤: proto: required field "{Unknown}" not set
還有其他事情正在發生。在Python中,您不能擁有包含重複子屬性的重複StructuredProperty(這與Go有相同的約束)。你在Python中脫離它的原因是你使用了LocalStructuredProperty,它使用的編碼方式與StructuredProperty非常不同 - 它將數據存儲爲字節字符串,編碼方式與對頂層實體進行編碼相同。但是你的Go代碼等同於使用StructuredProperty。也許你可以將它聲明爲一個字節串的數組並將它們分開解碼?因爲這就是Python中正在發生的事情。 –
我可以將'ModelA'中的'Messages'切換到'[] string'而不是'[ModelB'',但是我得到了我認爲是原始緩衝區編碼的字符串。我盡最大努力研究Go/python編碼/解碼protobuffers的方式,但其中的一部分超出了我的範圍。我認爲這個概念應該很簡單,將編碼後的字符串作爲一個新的protobuffer來解碼通過正常的過程,但我不確定是否有足夠的這個過程被導出供我使用,並且我很難重新創建。任何想法如何實現這一目標? – someone1