如何将实体附加到Go Lang中的数据存储区

时间:2017-10-08 18:57:30

标签: go google-cloud-datastore

需要有关如何在Google云数据存储中附加实体的信息。

Put函数总是被新值覆盖。

任何建议都会有所帮助。

09-OCT-2017:

我在代码下面使用,但仍然更新实体而不是附加。(它删除了旧的&更新了新值,但我想保留这两个值)

client, err := datastore.NewClient(ctx, projectID)
tx, err := client.NewTransaction(ctx)
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}

fmt.Fprint(w, input)
taskKey := datastore.NameKey("Entity", "stringID", nil)
var task Entity
if err := tx.Get(taskKey, &task); err != nil {
    log.Fatalf("tx.Get: %v", err)
}
task.Value = input
if _, err := tx.Put(taskKey, &task); err != nil {
    log.Fatalf("tx.Put: %v", err)
}
if _, err := tx.Commit(); err != nil {
    log.Fatalf("tx.Commit: %v", err)
}

2 个答案:

答案 0 :(得分:1)

你应该:

  • 首先获得实体,
  • 然后更改值
  • 然后更新数据存储区中的实体。

请咨询文档:https://cloud.google.com/datastore/docs/concepts/entities#updating_an_entity

  

要更新现有实体,请修改实体的属性   先前使用密钥检索并存储它:

tx, err := client.NewTransaction(ctx)
if err != nil {
        log.Fatalf("client.NewTransaction: %v", err)
}
var task Task
if err := tx.Get(taskKey, &task); err != nil {
        log.Fatalf("tx.Get: %v", err)
}
task.Priority = 5
if _, err := tx.Put(taskKey, task); err != nil {
        log.Fatalf("tx.Put: %v", err)
}
if _, err := tx.Commit(); err != nil {
        log.Fatalf("tx.Commit: %v", err)
}

答案 1 :(得分:1)

只能有一个实例,只有一个实体被相同的数据存储区绑定/表示。

实体(绑定到某个键)只能被覆盖,不能逐渐更新/扩展/附加。

因此,如果您已经保存了实体,要更新/修改它,您必须首先加载它,然后修改内存中的实体,并写出(保存)修改后的实体。此保存将覆盖数据存储区中的现有实体。

如果对于要存储多个值的属性,该属性的类型必须支持存储多个值。 Go中的Slices就是这样的类型。

因此,在您的示例中,您的实体应如下所示:

type Entity struct {
    Values []string 
}

加载现有Entity时,您必须将新值附加到其Values字段,如下所示(伪代码):

e := ... // load existing entity
e.Values = append(e.Values, input) // Append new data to Values
// And now save Entity (e) with the same key

在代码中:

client, err := datastore.NewClient(ctx, projectID)
tx, err := client.NewTransaction(ctx)
if err != nil {
    log.Fatalf("Failed to create client: %v", err)
}

fmt.Fprint(w, input)
taskKey := datastore.NameKey("Entity", "stringID", nil)
var task Entity
if err := tx.Get(taskKey, &task); err != nil {
    log.Fatalf("tx.Get: %v", err)
}
task.Values = append(task.Values, input)
if _, err := tx.Put(taskKey, &task); err != nil {
    log.Fatalf("tx.Put: %v", err)
}
if _, err := tx.Commit(); err != nil {
    log.Fatalf("tx.Commit: %v", err)
}

如果需要通过此Values属性进行索引,如果它包含许多值,则可能会遇到麻烦。有关详细信息,请参阅此可能的副本:App Engine Datastore: How to set multiple values on a property using golang?

如果您遇到此问题,则应考虑以不同的格式建模和存储数据,例如:保存在多个实体中,其中一个实体仅存储与其所属的键相关联的单个input