当前位置: 首页 > 面试题库 >

如何在Google App Engine数据存储区中添加动态属性

常波
2023-03-14
问题内容

我想做类似Python在应用程序引擎上支持的Expando模型的事情。

有时您不想提前声明属性。特殊的模型子类Expando更改其实体的行为,以便将分配的所有属性(只要它不以下划线开头)都保存到数据存储区。

如何在Go中执行此操作?


问题答案:

事先注意:

有2个API。具有导入路径的那个appengine/datastore使用通道作为参数。具有导入路径的另一个google.golang.org/appengine/datastore使用切片。根据您的情况调整以下示例。

具有动态属性的实体的关键是PropertyLoadSaver接口。通过实现此接口,您可以在保存时动态地构造要保存的实体的属性。

同样,不必自己执行此操作,Go
AppEngine平台提供了一种PropertyList类型,该类型基本上是属性列表(切片),Property并且也实现了PropertyLoadSaver

因此Go中的Expando模型为PropertyList。只需添加您希望实体拥有的属性,然后保存该PropertyList值即可。

这是一个例子:

c := appengine.NewContext(r)

props := datastore.PropertyList{
    datastore.Property{Name: "time", Value: time.Now()},
    datastore.Property{Name: "email", Value: "me@myhost.com"},
}

k := datastore.NewIncompleteKey(c, "DynEntity", nil)
key, err := datastore.Put(c, k, &props)
c.Infof("%v %v", key, err)

本示例将保存一个"DynEntity"具有2个动态属性的实体:"time""email"

由于PropertyList类型是切片,因此您还可以使用内置append()函数为其添加属性,因此也可以props像这样进行初始化:

var props datastore.PropertyList
props = append(props, datastore.Property{Name:"time", Value: time.Now()})
props = append(props, datastore.Property{Name:"email", Value: "me@myhost.com"})

map变成动态实体

PropertyLoadSaver界面并不复杂,我们可以实现它自己。在以下示例中,我在一个简单的自定义类型上实现了它map

type DynEnt map[string]interface{}

func (d *DynEnt) Load(props []datastore.Property) error {
    // Note: you might want to clear current values from the map or create a new map
    for _, p := range props {
        (*d)[p.Name] = p.Value
    }
    return nil
}

func (d *DynEnt) Save() (props []datastore.Property, err error) {
    for k, v := range *d {
        props = append(props, datastore.Property{Name: k, Value: v})
    }
    return
}

这是使用通道而不是切片的“旧”接口的实现的样子:

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
}

现在,我们可以DynEnt像Go中的任何其他地图一样使用我们的类型,并且由于它实现了PropertyLoadSaver,因此可以将其保存为实体(并且可以将
任何 实体加载到其中):

c := appengine.NewContext(r)

d := DynEnt{"email": "me@myhost.com", "time": time.Now()}

k := datastore.NewIncompleteKey(c, "DynEntity", nil)
key, err := datastore.Put(c, k, &d)
c.Infof("%v %v", key, err)


 类似资料:
  • 问题内容: 我有许多具有不同数量属性的不同对象。到目前为止,我已经将数据保存在XML文件中,该文件很容易允许数量不断变化的属性。但是我正在尝试将其移至数据库。 您首选的存储数据方式是什么? 到目前为止,我已经确定了一些策略: 在对象表中只有一个名为“属性”的字段,并在其中存储序列化或json化的数据。 将数据存储在两个表(对象,属性)中,并使用第三个表保存关系,使其成为真正的n:m关系。非常干净的

  • 我正在尝试在我的java spring项目中的swagger定义中添加新的属性。我已阅读文档并特别 https://springfox.github.io/springfox/docs/snapshot/#plugins 例如,我有这个定义: 我想要: 你能帮我在定义中添加meteo属性吗?在本例中,我的目标是以编程方式添加attribute,而不使用注释。

  • 预期结果:用循环去写,现在是写死的,当长度是2的时候是 obj= _tableArray[nodeList[0]].children[nodeList[1]]

  • 问题内容: 目标是创建一个行为类似db结果集的模拟类。 因此,例如,如果数据库查询使用表达式返回,那么我想看看: 刚开始我以为我可以这样做: 但返回一个属性对象。 用替换该行根本没有用。 那么在运行时创建实例属性的正确方法是什么? 问题答案: 我想我应该扩大这个答案,因为我年纪大一些并且比较聪明,并且知道发生了什么事。迟到总比不到好。 你可以动态地向类添加属性。但这很重要:你必须将其添加到类中。

  • 问题内容: 目前我正在使用这样的东西: 但是事实证明,AppEngine上的数据存储区中的ID不是从1开始的。我在数据存储区中有两个图像,其ID为6001和7001。 有没有更好的方法来检索随机图像? 问题答案: 数据存储是分布式的,因此ID是非顺序的:两个数据存储节点需要能够同时生成ID而不会引起冲突。 要获得随机实体,可以在创建时将0到1之间的随机浮点数附加到每个实体。然后进行查询,执行以下操

  • 通过SQL Developer,我向Oracle数据库添加了一个新的存储过程。它不仅列在存储过程列表中(与其他每个SP一起),而且我可以在SQL Developer上轻松地执行它。 问题是我似乎无法从外部应用程序执行它。数据库链接到它,我可以调用所有其他存储过程,但不能调用我刚刚创建的存储过程。我收到的错误消息是: ORA-06550:第1行,第7列:PLS-00201:标识符'SETDATE'必