我正在尝试持久化实体,并允许数据库生成密钥。不幸的是,我似乎无法从API中取出合成ID ...这就是我正在做的事情:
case "POST":
d,_ := ioutil.ReadAll( r.Body)
participant := new(Participant)
err := json.Unmarshal( d, &participant)
if err != nil {
serveError( c, w, err)
return
}
var key *datastore.Key;
if participant.ID == 0 {
// no id yet .. create an incomplete key and allow the db to create one.
key = datastore.NewIncompleteKey( c, "participant", parentKey)
} else {
// we have an id. use that to update
key = datastore.NewKey( c, "participant", "", participant.ID, parentKey)
}
// PERSIST!
putKey, e := datastore.Put( c, key, participant)
if e != nil {
serveError( c, w, e)
return
}
// Fetch back out of the database, presumably with my new ID
if e = datastore.Get( c, putKey, participant); e != nil {
serveError( c, w, e)
return
}
// send to the consumer
json,_ := json.Marshal( participant)
w.Write( json)
嗯,奇怪的是,ID始终为零!详细信息会保留,但我会使用相同的ID字段保留多个值。对于grins,这是对象定义:
type Participant struct {
ID int64
LastName string
FirstName string
Birthdate string
Email string
Cell string
}
跟进GET操作后,我会看到一个实体列表(是的,我创建的实体,我创建它们的次数)都是ID为零。
[
{"ID":0,"LastName":"Schmuck","FirstName":"Joe","Birthdate":"12-12-12","Email":"","Cell":""},
{"ID":0,"LastName":"Schmuck","FirstName":"Jane","Birthdate":"12-12-12","Email":"","Cell":""},
{"ID":0,"LastName":"Schmuck","FirstName":"Jane","Birthdate":"12-12-12","Email":"","Cell":""},
{"ID":0,"LastName":"Schmuck","FirstName":"Jane","Birthdate":"12-12-12","Email":"","Cell":""},
{"ID":0,"LastName":"Schmuck","FirstName":"Jane","Birthdate":"12-12-12","Email":"","Cell":""},
{"ID":0,"LastName":"Schmuck","FirstName":"Jane","Birthdate":"12-12-12","Email":"","Cell":""}
]
为了完整性,我还尝试使用ID值为零的NewKey(),但这给出了相同的结果。关于NewKey的API文档说明了(字符串)名称和ID都为零,创建了一个不完整的密钥 - 我不确定如何使字符串为零,但是nil不起作用。
有人帮助我弄清楚一旦指向文档的正确部分,可能会非常明显。
答案 0 :(得分:5)
我没有看到你在任何地方填充ID字段,所以它当然是0,因为那是该字段的零值。 AppEngine在存储时不会修改结构。当您使用不完整的键时,在放置struct时返回的新创建的键包含生成的IntId()。我认为你的困惑是由于假设文档从未说过而引起的。也就是说,AppEngine会为您自动填充存储数据中的ID字段。
因为在您的情况下,您希望结构的ID字段存储您在密钥中使用的ID,您可能希望在创建密钥时使用自己的唯一ID,而不是使用不完整的密钥。
当doc说一个字符串可以为零时,它指的是字符串类型的零值,这将是空字符串“”。您可以在此处详细了解零值:http://golang.org/ref/spec#The_zero_value
答案 1 :(得分:2)
我看不到你在Put之前实际更改ID值的位置?据我所知,它总是会出现0.我希望看到类似的东西:
// PERSIST!
putKey, e := datastore.Put( c, key, participant)
if e != nil {
// ...
}
// ...
participant.ID = putKey.IntID()
putKey, e = datastore.Put(c, putKey, participant)
未经测试,但您得到了图片...否则ID将始终为0.