英文:
How do I remove a field from a model in Google App Engine with Go?
问题
Go语言中与Python的delattr
或Java的Entity.removeProperty
等效的是什么?
我正在尝试从数据存储中删除属性,如下所述:
从数据存储中删除已删除的属性
英文:
What is the Go equivalent of Python delattr
or Java: Entity.removeProperty
?
I am trying to remove a property from the datastore as described here:
removing deleted properties from the datastore
答案1
得分: 4
为了从保存的实体中删除属性,您首先必须加载它,然后使用相同的键但不包含要删除的属性再次保存它。如果您想从所有保存的实体(某种类型的实体)中删除属性,您必须逐个加载和保存每个实体。(当然,您可以使用其他方法,如Query
和datastore.PutMulti()
来查询和保存多个实体。)
您可以基本上有两种方法从保存的实体中删除属性:
使用两个结构体:
您可以使用两个结构体:您的“旧”模型和“新”模型(不包含要删除的属性):
type Old struct {
Name string `datastore:"name"`
Removeme string `datastore:"removeme"`
}
type New struct {
Name string `datastore:"name"`
}
然后加载实体并重新保存它(使用相同的键):
c := appengine.NewContext(r)
// 构造键,例如:
k := datastore.NewKey(c, "Entity", "stringID", 0, nil)
e := new(Old)
if err = datastore.Get(c, key, e); err != nil {
// 数据存储错误。
return
}
e2 := New{e.Name}
if _, err = datastore.Put(c, k, &e2); err != nil {
// 数据存储错误。
}
使用PropertyList
或者您可以使用datastore.PropertyList
将任何实体加载到其中。
它基本上只是一个Property
的切片:
type PropertyList []Property
从此切片中删除您想要删除的属性,然后使用相同的键重新保存它。
基本上步骤是相同的:使用键加载实体,删除不需要的属性,然后重新保存它(使用相同的键)。
从切片中删除元素:
要删除切片a
中索引为i
的元素:
a = append(a[:i], a[i+1:]...)
// 或者
a = a[:i+copy(a[i:], a[i+1:])]
因此,基本上看起来像这样:
c := appengine.NewContext(r)
// 构造键,例如:
k := datastore.NewKey(c, "Entity", "stringID", 0, nil)
e := datastore.PropertyList{}
if err = datastore.Get(c, key, &e); err != nil {
// 数据存储错误。
return
}
// 循环遍历属性以找到要删除的属性:
for i, v := range e {
if v.Name == "removeme" {
// 找到了!
e = append(e[:i], e[i+1:]...)
break
}
}
if _, err = datastore.Put(c, k, &e); err != nil {
// 数据存储错误。
}
注意: 使用for range
从切片中删除多个元素时要小心。结果可能出乎意料,因为当您删除一个元素时,所有后续元素都会被移动,您可能会跳过一个元素。有关详细信息,请参阅此答案。
英文:
In order to remove a property from a saved entity, you have to load it first, and save it again with the same key but without the property you want to remove. If you want to remove a property from all saved entities (of a kind), you have to load and save each one-by-one. (Of course you may use other means like Query
's and datastore.PutMulti()
to query and save multiple entities.)
You can remove a property from a saved entity in basically 2 ways:
Using 2 structs:
You can use 2 structs: your old model and the new model (without the property you want to remove):
type Old struct {
Name string `datastore:"name"`
Removeme string `datastore:"removeme"`
}
type New struct {
Name string `datastore:"name"`
}
And load the entity and re-save it (with the same key):
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
}
Using PropertyList
Or you can use the datastore.PropertyList
to load any entity into it.
It's basically just a slice of Property
's:
type PropertyList []Property
Remove the property (or properties) you want to delete from this slice, and re-save it with the same key.
Basically the steps are the same: load an entity with a key, remove unwanted properties, and resave it (with the same key).
Remove an element from a slice:
To delete the element from slice a
at index i
:
a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
So basically it looks something like this:
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
}
Note: Be careful when removing multiple elements from a slice using for range
. Result might be unexpected as when you remove an element, all subsequent elements are shifted and you may skip an element. For details see this answer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论