Reputation: 612
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
Upvotes: 2
Views: 784
Reputation: 417512
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:
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
}
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.
Upvotes: 4