Google Go没有生成唯一标识符?

时间:2013-01-04 06:08:09

标签: google-app-engine google-cloud-datastore go

我正在尝试持久化实体,并允许数据库生成密钥。不幸的是,我似乎无法从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不起作用。

有人帮助我弄清楚一旦指向文档的正确部分,可能会非常明显。

2 个答案:

答案 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.