将许多 PropertyList 放入 Google App Engine 数据存储区(在 Go 中)并使用 Query.GetAll 再次加载它们
Posted
技术标签:
【中文标题】将许多 PropertyList 放入 Google App Engine 数据存储区(在 Go 中)并使用 Query.GetAll 再次加载它们【英文标题】:Putting many PropertyList's into Google App Engine datastore (in Go) and loading them again with Query.GetAll 【发布时间】:2012-02-14 09:53:11 【问题描述】:我将实体(作为datastore.PropertyList
)放入数据存储区,如下所示:
// save one
var plist datastore.PropertyList = make(datastore.PropertyList, 3)
plist = append(plist, datastore.Property "name", "Mat", false, false )
plist = append(plist, datastore.Property "age", "29", false, false )
plist = append(plist, datastore.Property "location", "London", false, false )
key := datastore.NewIncompleteKey(context, "Record", nil)
datastore.Put(context, key, &plist)
// save another one
var plist datastore.PropertyList = make(datastore.PropertyList, 3)
plist = append(plist, datastore.Property "name", "Laurie", false, false )
plist = append(plist, datastore.Property "age", "27", false, false )
plist = append(plist, datastore.Property "location", "London", false, false )
key := datastore.NewIncompleteKey(context, "Record", nil)
datastore.Put(context, key, &plist)
一切正常(尽管上面的代码现在更像是伪代码)。我可以单独加载它们,datastore.PropertyList
与每个字段一起作为自己的datastore.Property
出现。
但是,当我尝试使用 Query
检索其中许多时,它失败了:
query := datastore.NewQuery("Record")
plists := make(datastore.PropertyList, 0, 10)
keys, err := query.GetAll(context, &plists)
我收到以下错误:
datastore: cannot load field "age" into a "datastore.Property": no such struct field
它似乎没有抱怨Name
,因为这恰好是datastore.Property
的有效属性,所以我如何让它按预期加载项目,plists
中的每个项目都是datastore.PropertyList
而不是 datastore.Property
?
【问题讨论】:
顺便说一句,我正在执行与此文件中的代码完全相同的操作:hyk-proxy.googlecode.com/svn-history/r256/trunk/v2/gae/src/go/… - 特别是GetAllGroups
方法,它们以相同的方式加载许多项目。
【参考方案1】:
我将实现更改为使用 PropertyLoadSaver
接口 - 您可以在我们新的 Active Record 数据存储样式包装器中看到它运行良好:http://github.com/matryer/gae-records(请参阅 record.go
类型的 Load
和 Save
方法)
【讨论】:
【参考方案2】:GetAll 在给定的上下文中运行查询并返回与该查询匹配的所有键,并将值附加到 dst。 dst 必须是指向结构、结构指针或映射的slice 的指针。如果 q 是“仅键”查询,GetAll 将忽略 dst 并仅返回键。
根据following post,go 数据存储模块还不支持 PropertyList。
改为使用指向 datastore.Map 切片的指针。
另请注意,您需要调用make([]T, n)
才能制作T
的切片,而不是make(T, n)
【讨论】:
【参考方案3】:尝试使用大写字母来编写字段名称,例如,不要写age
,而是写成Age
。这告诉 Go 您的字段已导出(它类似于公共变量的概念,但比这更进一步)。
根据Go datastore documentation(查看函数部分中的Get方法),Get
或GetAll
方法调用将返回ErrFieldMismatch
“当一个字段被加载到不同的类型或者当目标结构中缺少或未导出字段时。仅当 dst 是结构指针时才返回 ErrFieldMismatch。”。我的最佳猜测是,由于您将其存储为具有未导出名称的 PropertyList
,并且由于数据存储在其模型中是灵活的,因此由于它们的小写字母,原始值将被视为未导出。
我目前遇到同样的错误,但我设法将其追踪到是由于一些空字段造成的。
如果这解决了您的问题,请告诉我。
【讨论】:
以上是关于将许多 PropertyList 放入 Google App Engine 数据存储区(在 Go 中)并使用 Query.GetAll 再次加载它们的主要内容,如果未能解决你的问题,请参考以下文章