注:古い記事の為、内容が最新ではない可能性がありますm(_ _)m
GAE/Go Datastore
どうもマツウラです。
App Engineを使用するにあたって欠かせないDatastore。
Go言語での使用方法はどのようになっているのでしょうか?
公式チュートリアルを参考に簡単に見てゆきます。
参考:Go — Google Developers Entities, Properties, and Keys
PUT, GET, UPDATE, DELETE
まずは基本的なデータストアへのエンティティの保存、取得、更新、削除です。
簡単な例を見てみます。
次の例ではエラー処理を省略しています。
// プロパティ名は大文字で始めるよう注意してください!! // 小文字で付けたい場合はタグを使用します。 type Employee struct { Name string Role string HireDate time.Time Account string } func handler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) // App Engineの各種サービスとのコミュニケーションに使用します。今回はDatastoreです。 e1 := Employee{ Name: "Joe Citizen", Role: "Manager", HireDate: time.Now(), Account: user.Current(c).String(), } // put key := datastore.NewIncompleteKey(c, "employee", nil) key, err := datastore.Put(c, key, &e1) // get var e2 Employee err = datastore.Get(c, key, &e2) // update key, err = datastore.Put(c, key, &e2) // delete err = datastore.Delete(c, key) }
エンティティの作成
func Put(c appengine.Context, key *Key, src interface{}) (*Key, error)
Goではデータストアエンティティは構造体の値から作成されます。
その際、構造体のフィールドがエンティティのプロパティとなります。
格納する値を設定し、keyを作成、datastore.Put()に構造体オブジェクトとkeyの両方を渡すことでエンティティを作成します。
Keyの作成方法には二通りあります。
datastore.NewIncompleteKey(c appengine.Context, kind string, parent *Key) *Key
datastore.NewKey(c appengine.Context, kind, stringID string, intID int64, parent *Key) *Key
一意のIDを持った完全なKeyを作成するNewKeyメソッドとは異なり、NewIncompleteKeyメソッドはIDを持たない不完全なKeyを作成して返します。
不完全なKeyはデータストアにエンティティと格納される際に、データストアにより自動的に数値IDが付けられます。
Key名を割り当てて、datastore.NewKeyに文字列IDを設定するには次のように行います。
key := datastore.NewKey( c, // appengine.Context "Employee", // 種類 "asalieri", // 文字列ID; 空であれば非文字列IDとなる 0, // 整数値ID; 0の場合、自動的に生成されます。文字列IDが指定されている場合は無視されます nil //親キー; nilならば親が無いことになります。 )
データストアが自動的に整数値IDを割り当てるには、空の文字列ID引数を使います。
key := datastore.NewKey(c, "Employee", "", 0, nil) // こちらと同等です。 // key := datastore.NewIncompleteKey(c, "Employee", nil)
エンティティの取得
func Get(c appengine.Context, key *Key, dst interface{}) error
データストアからエンティティを取得するには、Keyと構造体ポインタをGet()に渡します。
Get()を実行すると、渡した構造体ポインタにエンティティが読み込まれます。
エンティティを取得する際に使用するGetですが、次の注意点があります。
- dstの一致しなかった構造体フィールドの値は変更されません
- 一致したスライス型フィールドは値が追加される前にリセットされません
そのため、Getの呼び出しではゼロ値の構造体ポインタを渡すことが推奨されています。
エンティティの更新
更新においても作成同様にPut()を使用します。
エンティティの作成、および更新で使用するdatastore.Put()ですが、データストアAPIは作成と更新を区別しません。
そのため、Keyが既存のエンティティを示す場合は上書きします。
ゼロ値の構造体に更新値だけ設定して上書きすることで、既存のフィールド値を誤って消してしまわないよう注意して下さい。
エンティティの削除
func Delete(c appengine.Context, key *Key) error
削除は、削除するエンティティのkeyをDelete()に渡すことで行います。
バッチ処理
次に複数のエンティティを一度に処理する方法です。
Put(), Get(), Delete()それぞれに対応するdatastore.PutMulti, datastore.GetMulti, datastore.DeleteMultiメソッドが用意されています。
次はこれらメソッドの簡単な使用例です。
// batch put err := datastore.RunInTransaction(c, func(c appengine.Context) error { _, err := datastore.PutMulti(c, []*datastore.Key{k1, k2, k3}, []interface{e1, e2, e3}) return err }, nil) // batch get entities := make([]*Person, 3) err := datastore.GetMulti(c, []*datastore.Key{k1, k2, k3}, entities) // batch delete err := datastore.DeleteMulti(c, []*datastore.Key{k1, k2, k3})
上記の例でPUTの際にトランザクション内でデータストア操作を実行しています。
これはPutMultiおよびDeleteMultiについては一部のエンティティ操作については成功し、その他が失敗する恐れがあるためです。
エンティティを作成、削除するためそれら全てのエンティティについて操作が完全に成功、または失敗することを保証したい場合はトランザクションを使用して下さい。
func GetMulti(c appengine.Context, key []*Key, dst interface{}) error func PutMulti(c appengine.Context, key []*Key, src interface{}) ([]*Key, error) func DeleteMulti(c appengine.Context, key []*Key) error
まず第一回としてGo言語でApp Engine Datastoreへのデータの保存、取得、更新、削除の基本的な動作を確認しました。
次回はクエリについて触れていこうと思います。