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

huangapple go评论149阅读模式
英文:

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

为了从保存的实体中删除属性,您首先必须加载它,然后使用相同的键但不包含要删除的属性再次保存它。如果您想从所有保存的实体(某种类型的实体)中删除属性,您必须逐个加载和保存每个实体。(当然,您可以使用其他方法,如Querydatastore.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.

huangapple
  • 本文由 发表于 2015年9月8日 20:17:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/32457629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定