如何使用Go从Google App Engine中的模型中删除字段?

时间:2015-09-08 12:17:31

标签: google-app-engine go google-cloud-datastore

什么是Go等价的Python delattr或Java:Entity.removeProperty

我正在尝试从数据存储中删除属性,如下所述: removing deleted properties from the datastore

1 个答案:

答案 0 :(得分:4)

要从已保存的实体中删除属性,必须先将其加载,然后使用相同的密钥再次保存,但不要删除要删除的属性。如果要从所有已保存的实体(某种)中删除属性,则必须逐个加载并保存每个属性。 (当然,您可以使用其他方式,例如Querydatastore.PutMulti()来查询和保存多个实体。)

您可以通过两种方式从已保存的实体中删除属性:

使用2个结构:

您可以使用2个结构:模型和模型(不包含要删除的属性):

type Old struct {
    Name     string `datastore:"name"`
    Removeme string `datastore:"removeme"`
}

type New struct {
    Name     string `datastore:"name"`
}

加载实体并重新保存(使用相同的密钥):

c := appengine.NewContext(r)
// Constructing the key, for example:
k := datastore.NewKey(c, "Entity", "stringID", 0, nil)

e := new(Old)
if err = datastore.Get(c, key, e); err != nil {
    // Datastore error.
    return
}

e2 := New{e.Name}
if _, err = datastore.Put(c, k, &e2); err != nil {
    // Datastore error
}

使用PropertyList

或者您可以使用datastore.PropertyList将任何实体加载到其中。

它基本上只是Property的一部分:

type PropertyList []Property

从此切片中删除要删除的属性(或属性),然后使用相同的密钥重新保存。

基本上步骤是相同的​​:使用密钥加载实体,删除不需要的属性,然后重新保存(使用相同的密钥)。

从切片中删除元素:

要从索引a处的切片i中删除该元素:

a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]

所以基本上它看起来像这样:

c := appengine.NewContext(r)
// Constructing the key, for example:
k := datastore.NewKey(c, "Entity", "stringID", 0, nil)

e := datastore.PropertyList{}
if err = datastore.Get(c, key, &e); err != nil {
    // Datastore error.
    return
}

// Loop over the properties to find the one we want to remove:
for i, v := range e {
    if v.Name == "removeme" {
        // Found it!
        e = append(e[:i], e[i+1:]...)
        break
    }
}

if _, err = datastore.Put(c, k, &e); err != nil {
    // Datastore error
}

注意:使用for range从切片中删除多个元素时要小心。结果可能是意外的,因为当您删除元素时,所有后续元素都会移位,您可以跳过元素。有关详细信息,请参阅this answer