概要
https://cloud.google.com/datastore/docs/?hl=ja
NoSQL
トランザクションをサポートしていたりSQLと似た公文のGQLが使えるのが特徴。
ダッシュボードからCloud Data Storeにデータ(エンティティ)を追加する
以下のクイックスタートを試してみる。
https://cloud.google.com/datastore/docs/quickstart?hl=ja
プロジェクトを選択していた場合ロケーションは表示されない。
https://console.cloud.google.com/datastore/entities/query/kind
からエンティティを作成できる。
RDBでいうところの
名前空間はスキーマ
種類はテーブル名
キー識別子は主キー
プロパティはカラム
エンティティはデータ
といったところだろうか。
エンティティ作成画面では種類を先に入力していないとプロパティがクリアされてしまう。せっかく入力したのに...
種類を入力してプロパティを追加して作成ボタンを押下したら、データが追加されクエリを利用してフィルタすることができるようになる。
データ追加が面倒すぎるのでできればスプレッドシートなどから引っ張れるようにしたい。
GoプログラムからCloud Data Storeにデータ(エンティティ)を追加する
プログラムからデータ操作できるようにしたい。
https://cloud.google.com/datastore/docs/concepts/entities?hl=ja
https://cloud.google.com/datastore/docs/datastore-api-tutorial?hl=ja
がドキュメント
コマンド
go get github.com/GoogleCloudPlatform/golang-samples/datastore/tasks
でサンプルが取得できる。あるいはどこかのタイミングで取得済みかもしれない。
ターミナル(PowerShell)からtasksディレクトリに移動して
go run tasks.go
で確認可能。ローカルから操作する場合認証が必要のようだ。
https://cloud.google.com/docs/authentication/getting-started
ダッシュボードの APIとサービス → 認証情報 から
https://console.cloud.google.com/apis/credentials
jsonファイルをダウンロードして以下のコマンド(PowerShell)
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\[FILE_NAME].json"
上記は環境変数:GOOGLE_APPLICATION_CREDENTIALSにダウンロードしたファイルのパスを設定している(一時的)
サンプルを動かす場合以下も必要。project-idはGCP(GAE)のプロジェクトID
$env:DATASTORE_PROJECT_ID="project-id"
以上サンプルの動作をまとめるとローカルからデータ追加する手順は。
コマンドからgcloudにログイン
gcloud auth login
普段から使用していれば恐らく認証済みdatastore.NewClient 時はprojectIDを指定する。
プロジェクトIDはダッシュボードから
認証情報を設定する。
下記はPowerShellの例。
$env:GOOGLE_APPLICATION_CREDENTIALS="D:\dl\aaaa-09fc5aa8ed9e1e.json"
jsonファイルはprojectにでも入れて(ただし公開しないように)おいたほうがいいかもしれない。ちなみにローカルサーバで動かすときにクラウド上のデータストアを参照したい場合
env_variables: GOOGLE_APPLICATION_CREDENTIALS: D:\dl\aaaa-09fc5aed9e1e.json
のようにすると良い
あるいは上記コマンドは一時的に環境変数に設定しているだけなので永続化するか。
ただそうするとプロジェクトを切り替えるのが面倒になってしまう。
下記がシンプルなデータ追加のサンプルコード
script.go
package main
import (
"context"
"fmt"
// Imports the Google Cloud Storage client package.
"cloud.google.com/go/datastore"
)
// TestModel データモデル
type TestModel struct {
Test string
}
func main() {
entity := &TestModel{
Test: "Test",
}
ctx := context.Background()
// ダッシュボードから確認できるプロジェクトIDを指定する
projectID := "projectID"
client, err := datastore.NewClient(ctx, projectID)
if err != nil {
fmt.Printf("datastore client 作成に失敗: %v", err)
}
// DataStore のkind
kind := "kindName"
key := datastore.IncompleteKey(kind, nil)
if _, err := client.Put(ctx, key, entity); err != nil {
fmt.Println(err)
}
}
go run script.go
ダッシュボードにアクセスして
https://console.cloud.google.com/datastore/entities
"kindName"でフィルタしてみるとデータが登録されていることがわかる。

特に制御等をかけていないので実行した数だけデータが登録される。
ここまで出来れば後は自由にデータを投入できる。
ちなみに複数のデータを投入したい場合
// DataStore のkind
projectID := "projectID "
kind := "kindname"
ctx := context.Background()
client, err := datastore.NewClient(ctx, projectID)
if err != nil {
fmt.Printf("datastore client 作成に失敗: %v", err)
}
data := strings.Split(test, "\n")
var keys []*datastore.Key
// fmt.Println((len(data)))
var entities []BattleModel
for r := 0; r < len(data); r++ {
rowData := strings.Split(data[r], "\t")
// fmt.Println(data[r])
entity := TestModel{}
entity.a = rowData[0]
entity.b = rowData[1]
entities = append(entities, entity)
key := datastore.IncompleteKey(kind, nil)
keys = append(keys, key)
}
_, err = client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
_, err := tx.PutMulti(keys, entities)
return err
})
といった具合になる(keysの型がわからなくてハマった)
keyをエンティティごとに指定できるということは全く違うデータも投入できそうだ(恐らくやらない)
rpc error: code = InvalidArgument desc = operating on too many entity groups in a single transaction.
1トランザクションで変更可能なデータは25までという制限があるようだ
https://qiita.com/hichika/items/180f1820caf05b275a22#operating-on-too-many-entity-groups-in-a-single-transaction
GoプログラムからCloud Data Storeにのデータをクエリする
プログラムからクエリする方法は以下。それほど難しくはない
https://cloud.google.com/datastore/docs/concepts/queries?hl=ja#datastore-datastore-basic-query-go
以下にリファレンスが載っている(英語)
https://godoc.org/cloud.google.com/go/datastore
list.go
package main
import (
"context"
"fmt"
"time"
// Imports the Google Cloud Storage client package.
"cloud.google.com/go/datastore"
)
// TestrModel データモデル
type TestModel struct {
Test time.Time
}
func main() {
ctx := context.Background()
// ダッシュボードから確認できるプロジェクトIDを指定する
projectID := "projectID"
client, _ := datastore.NewClient(ctx, projectID)
kind := "kind"
q := datastore.NewQuery(kind).Limit(100).Order("created")
var entities []TestModel
client.GetAll(ctx, q, &entities)
fmt.Println(entities)
}
上記種類"kind"から100件取得してcreatedでソートする処理になる。
Orderはそのままだと昇順。.Order("-created")のようにプロパティ名に-をつけると降順になる。
Filterを使用することで絞り込みもできる。
FilterとOrderが同時に使用する場合まずFilterしたプロパティでOrderを指定しないといけないようだ。。
いろいろ試してみて追記予定