csm*_*lon 1 google-app-engine struct go data-structures google-cloud-datastore
我遇到了数据存储的严重问题,似乎没有任何解决方法。
我正在使用 Google Appengine 数据存储包将投影查询结果拉回到 Appengine 内存中进行操作,这是通过将每个实体表示为结构来完成的,每个结构字段对应于一个属性名称,如下所示:
type Row struct {
Prop1 string
Prop2 int
}
Run Code Online (Sandbox Code Playgroud)
这非常有效,但我已将查询扩展为读取其他包含空格的属性名称。虽然查询运行良好,但它无法将数据拉回结构中,因为它希望将给定值放入具有相同命名约定的结构中,并且我收到此类错误:
datastore: cannot load field "Viewed Registration Page" into a "main.Row": no such struct field
Run Code Online (Sandbox Code Playgroud)
显然Golang无法表示这样的结构体字段。有一个相关类型的字段,但没有明显的方法告诉查询将其放置在那里。
这里最好的解决方案是什么?
干杯
实际上,Go 支持使用标签将实体属性名称映射到不同的结构字段名称(有关详细信息,请参阅此答案:What are the use(s) for Tags in Go?)。
例如:
type Row struct {
Prop1 string `datastore:"Prop1InDs"`
Prop2 int `datastore:"p2"`
}
Run Code Online (Sandbox Code Playgroud)
datastore但是,如果您尝试使用包含空格的属性名称,则包的Go 实现会出现混乱。
总结一下:你不能将带有空格的属性名称映射到 Go 中的结构字段(这是一个实现限制,将来可能会改变)。
但好消息是您仍然可以加载这些实体,只是不能加载到结构值中。
您可以将它们加载到类型的变量中datastore.PropertyList。datastore.PropertyList基本上是 的一部分datastore.Property,其中Property是一个保存属性名称、其值和其他信息的结构。
可以这样做:
k := datastore.NewKey(ctx, "YourEntityName", "", 1, nil) // Create the key
e := datastore.PropertyList{}
if err := datastore.Get(ctx, k, &e); err != nil {
panic(err) // Handle error
}
// Now e holds your entity, let's list all its properties.
// PropertyList is a slice, so we can simply "range" over it:
for _, p := range e {
ctx.Infof("Property %q = %q", p.Name, p.Value)
}
Run Code Online (Sandbox Code Playgroud)
"Have space"如果您的实体具有value 的属性"the_value",您将看到例如:
2016-05-05 18:33:47,372 INFO: Property "Have space" = "the_value"
Run Code Online (Sandbox Code Playgroud)
请注意,您可以datastore.PropertyLoadSaver在结构上实现类型并在幕后处理此问题,因此基本上您仍然可以将此类实体加载到结构值中,但您必须自己实现。
但要争取实体名称和属性名称不包含空格。如果你允许这些,你的生活就会变得更加艰难和痛苦。