什么是Go等价的Python delattr
或Java:Entity.removeProperty
?
我正在尝试从数据存储中删除属性,如下所述: removing deleted properties from the datastore
答案 0 :(得分:4)
要从已保存的实体中删除属性,必须先将其加载,然后使用相同的密钥再次保存,但不要删除要删除的属性。如果要从所有已保存的实体(某种)中删除属性,则必须逐个加载并保存每个属性。 (当然,您可以使用其他方式,例如Query
和datastore.PutMulti()
来查询和保存多个实体。)
您可以通过两种方式从已保存的实体中删除属性:
您可以使用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。