Google App Engine(GAE)で動作しているアプリケーションがあります。
DBとしてCloud Datastoreを利用しており、開発環境を一新するにあたって、本番のデータをローカルでもそのまま使おうと思いました。
以前 https://noboru.hatenablog.jp/entry/20130212/1360679541 を書いていましたが、いろんなものがバージョンアップされていたので、最新の方法でやってみようと思います。
前提
Cloud Datastoreにデータが溜まっていること。
ローカルでは、 dev_appserver.py
を利用していること。
gcloud
などのツールが設定済みで、対象のプロジェクトに接続可能なこと。
データのエクスポート
まずは、Cloud Datastoreの情報をエクスポートします。
エクスポート先として、Cloud Storageを指定する必要があるので、バケットを作成しておきます。
(今回は、いつの間にかあったものを利用しました。GAEの環境と同時に作成された?)
バケット名: my-android-server.appspot.com
保存先フォルダ: datastore
gcloud datastore export --namespaces="(default)" gs://my-android-server.appspot.com/datastore
これにより、Cloud Storageの対象のフォルダに、
1つの datastore.overall_export_metadata
ファイルと、
default_namespace
フォルダに含まれる大量の output-0
のようなバイナリファイルができます。
データをローカルにダウンロード
公式: https://cloud.google.com/storage/docs/gsutil/commands/cp
次のインポートでは、ローカルのデータを利用するため、一旦ローカルにデータを持ってきておきます。
大量にファイルがあるのですが、Webのダッシュボードからは一括でダウンロードする手段が見あたらなかったので、 gsutil
を利用してダウンロードします。
gsutil cp -r gs://my-android-server.appspot.com/datastore .
これにより、カレントディレクトリに datastore
ディレクトリが作成され、配下のファイルもダウンロードされます。
ローカルサーバの起動
公式: https://cloud.google.com/appengine/docs/standard/python/tools/using-local-server
Google App Engineのローカル開発環境を立ち上げるため、 dev_appserver.py
を起動します。
dev_appserver.py app.yaml --datastore_path=`pwd`/database/db.datastore -A my-android-server --support_datastore_emulator True
この際に、 --datastore_path
を指定しておくことで、ファイル位置を指定しておきます。(削除など
また、 -A
でAPP_IDを指定しておかないと、次のcurlで指定するPROJECT_IDがうまく指定できないようです。
起動時のログで、下記のようにCloud Datastore emulatorのアドレスが表示されます。
INFO 2019-03-09 04:51:02,232 datastore_emulator.py:155] Starting Cloud Datastore emulator at: http://localhost:16895
ローカルのDatastoreにデータをインポート
公式: https://cloud.google.com/datastore/docs/tools/emulator-export-import
https://cloud.google.com/datastore/docs/reference/admin/rest/v1/projects/import
これと同じものが実装されているようです。
curl -X POST "localhost:16895/v1/projects/my-android-server:import" -H 'Content-Type: application/json' -d '{"inputUrl":"datastore/datastore.overall_export_metadata"}'
ポートは、起動時に表示されていたCloud Datastore emulatorのポートを指定します。
inputUrl
の指定は、相対パスで良いようです。
PROJECT_ID
として、サーバ起動時に -A
として渡していた APP_ID
を指定します。
レスポンスとして、下記のような結果が返ります。
{
"name": "projects/my-android-server/operations/72cc047a2c254d85b703adb6ed5ac35f",
"metadata": {
"@type": "type.googleapis.com/google.datastore.admin.v1.ImportEntitiesMetadata",
"common": {
"startTime": "2019-03-09T05:01:28.442Z",
"endTime": "2019-03-09T05:01:37.128Z",
"operationType": "IMPORT_ENTITIES",
"state": "SUCCESSFUL"
},
"entityFilter": {
},
"inputUrl": "datastore/datastore.overall_export_metadata"
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.protobuf.Empty"
}
}
(ちなみに、 PROJECT_ID
の指定が間違っていても "state": "SUCCESSFUL"
となりますが、次の確認の部分で表示されない状態になります。)
確認
http://localhost:8000/datastore をブラウザで開いて、本番と同じデータが表示されれば成功です。
参考