3

エンティティを永続化して、データベースがキーを生成できるようにしようとしています。残念ながら、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フィールドで複数の値が保持されます。にやにや笑いの場合、オブジェクトの定義は次のとおりです。

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は機能しません。

ドキュメントの正しいセクションを指摘すると、おそらく驚くほど明白なことを誰かが理解するのを手伝ってくれます。

4

2 に答える 2

5

IDフィールドにデータが入力されていないので、もちろん0になります。これは、そのフィールドのゼロ値だからです。AppEngineは、構造体を保存するときに構造体を変更しません。構造体を配置したときに返される新しく作成されたキーには、不完全なキーが使用されたときに生成されたIntId()が含まれます。あなたの混乱は、ドキュメントが決して言っていないことを想定することによって引き起こされたと思います。つまり、AppEngineは保存されたデータのIDフィールドに自動入力します。

あなたの場合、構造体のIDフィールドにキーで使用されるIDを格納する必要があるため、不完全なキーを使用する代わりに、キーを作成するときに独自のIDを生成する必要があります。

ドキュメントが文字列がゼロになる可能性があると言っている場合、それは空の文字列""になる文字列型のゼロ値を参照しています。ゼロ値の詳細については、http://golang.org/ref/spec#The_zero_valueをご覧ください。

于 2013-01-04T06:36:27.157 に答える
2

プットの前に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になります。

于 2013-01-04T06:38:58.997 に答える