本文介绍了如何在Google应用引擎数据存储中使用动态属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我想做类似 Expando Model 的内容python支持应用程序引擎。 如何在Go中执行此操作? 解决方案 div> 提前注意: 有2个API。导入路径为 appengine / datastore 的版本使用通道作为参数。另一个使用导入路径 google.golang.org/appengine/datastore 使用切片。根据你的情况调整上面的例子。有关详细信息,请参阅此问题:如何正确导入Golang appengine? 具有动态属性的实体的关键是 PropertyLoadSaver 界面。通过实现这个接口,您可以动态地 - 在保存时间 - 构造要保存的实体的属性。 另外,无需自己做这个Go AppEngine平台提供 PropertyList 类型,它基本上是属性的列表(片段) Property ,它也实现 PropertyLoadSaver 。 因此Go中的Expando模型是 PropertyList 。只需添加你希望实体拥有的属性,并保存这个 PropertyList 值。 下面是一个例子: c:= appengine.NewContext(r) 道具:= datastore.PropertyList { datastore.Property {Name:time,Value:time.Now()}, datastore.Property {名称:email,值:[email protected]}, } k:= datastore.NewIncompleteKey(c,DynEntity,nil) key,err:= datastore.Put(c,k,&props) c。 Infof(%v%v,key,err) 这个例子保存一个名为DynEntity包含2个动态属性:time和email PropertyList 类型是一个切片,所以您也可以使用内置的 https://golang.org/pkg/builtin/#appendrel =nofollow noreferrer> append() 函数为它添加属性,所以你也可以像这样初始化道具: var props datastore.PropertyList props = append(props,datastore.Property {Name:time,Value:time.Now()}) props = append(props, datastore.Property {名称:email,值:[email protected]}) 将 map 转换为动态实体 PropertyLoadSaver 界面并不复杂,我们可以自己实现。在下面的示例中,我将它实现为一个简单的 map 的自定义类型: type DynEnt map [string] interface {} func(d * DynEnt)加载(ch //注意:想要清除地图中的当前值或创建一个新地图 for p:= range ch {//读取直到通道关闭(* d)[p.Name] = p.Value func(d * DynEnt)保存(ch chan defer close(ch)/ / Channel必须关闭 for k,v:= range * d { ch } return nil $ / code> 现在我们可以使用我们的 DynEnt 类型就像Go中的任何其他地图一样,并且由于它实现了 PropertyLoadSaver ,所以它可以保存为一个实体(并且任何实体都可以加载到它): c:= appengine.New上下文(r) d:= DynEnt {email:[email protected],time:time.Now()} k:= datastore。 NewIncompleteKey(c,DynEntity,nil) key,err:= datastore.Put(c,k,& d) c .fof(%v%v,key,err) I want to do something like the Expando Model that python supports on app engine. How can I do this in Go? 解决方案 Note beforehand:There are 2 APIs. The one with import path appengine/datastore uses channels as arguments. The other with import path google.golang.org/appengine/datastore uses slices. Adjust the example above to your case. See this question for details: How to correctly import Golang appengine?The key to an entity with dynamic properties is the PropertyLoadSaver interface. By implementing this interface you can dynamically - at save time - construct the properties of the entity to be saved.Also to not have to do this yourself the Go AppEngine platform provides a PropertyList type which is basically a list (a slice) of properties Property and it also implements PropertyLoadSaver.So the Expando model in Go is PropertyList. Just add the properties you want your entity to have, and save this PropertyList value.Here is an example:c := appengine.NewContext(r)props := datastore.PropertyList{ datastore.Property{Name: "time", Value: time.Now()}, datastore.Property{Name: "email", Value: "[email protected]"},}k := datastore.NewIncompleteKey(c, "DynEntity", nil)key, err := datastore.Put(c, k, &props)c.Infof("%v %v", key, err)This example saves an entity named "DynEntity" with 2 dynamic properties: "time" and "email".As the PropertyList type is a slice, you can also use the builtin append() function to add properties to it, so you could also initialize props like this:var props datastore.PropertyListprops = append(props, datastore.Property{Name:"time", Value: time.Now()})props = append(props, datastore.Property{Name:"email", Value: "[email protected]"})Turning a map into a dynamic entityThe PropertyLoadSaver interface is not complicated, we can implement it ourselves. In the following example I implement it on a custom type which is a simple map:type DynEnt map[string]interface{}func (d *DynEnt) Load(ch <-chan datastore.Property) error { // Note: you might want to clear current values from the map or create a new map for p := range ch { // Read until channel is closed (*d)[p.Name] = p.Value } return nil}func (d *DynEnt) Save(ch chan<- datastore.Property) error { defer close(ch) // Channel must be closed for k, v := range *d { ch <- datastore.Property{Name: k, Value: v} } return nil}Now we can use our DynEnt type just like any other maps in Go, and since it implements PropertyLoadSaver, it can be saved as an entity (and any entities can be loaded into it):c := appengine.NewContext(r)d := DynEnt{"email": "[email protected]", "time": time.Now()}k := datastore.NewIncompleteKey(c, "DynEntity", nil)key, err := datastore.Put(c, k, &d)c.Infof("%v %v", key, err) 这篇关于如何在Google应用引擎数据存储中使用动态属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-19 21:24