15. ダンプとリストア

この機能は Kay-0.2.0 以降で使えます。

15.1. 概要

最新の appengine には、dump/restore 機能が付きました。この機能を使うと全てのデータをダンプ/リストアできます。ただし kind ひとつに付きコマンドを実行する必要があり、また kind をいちいち指定しなければなりません。Kay ではもっと簡単に全てのデータをダンプ/リストアできるようになっています。

これからいくつかのコマンド例を紹介しますが、これらのコマンドは全てプロジェクトディレクトリ内で実行してください。

15.2. サーバーからダンプする

サーバーからダンプするには、下記のコマンドを実行します。このコマンドは app.yaml の値からアクセスするサーバーを自動的に決めますのでその値に注意して実行してください。

$ python manage.py dump_all -n 20090919

ユーザー名とパスワードを聞かれるので答えると、 _backup/20090919 というディレクトリ内にデータがダンプされます。このディレクトリにある .dat で終るファイルが実際のデータを含んだファイルです。-n で指定するディレクトリにデータやログファイルなどが書かれます。

15.3. サーバーのデータをクリアする

サーバーのデータを全て消去するには、下記のようにします。

$ python manage.py clear_datastore [-c]

-c を付けると memcache のデータも全て消去します。

15.4. サーバーにダンプしたデータをリストアする

下記のコマンドを実行すれば、 20090919 ディレクトリ内のデータをサーバー側に書き戻せます。

$ python manage.py restore_all -n 20090919

リストア前には、データを一度クリアする必要があるケースもあります。 (TODO: どんなケースでクリアする必要があるか説明)

15.5. ローカルの開発サーバーからデータをダンプする

ローカルの開発サーバーからデータをダンプ/リストアするためには、ローカルの開発サーバーが起動している必要があります。ダンプするには、下記のようにします。サーバーからダンプする時との違いは -u パラメータで remote API の URL を指定するだけです。

$ python manage.py dump_all -n 20090919local -u http://localhost:8080/remote_api

15.6. ローカルのデータをクリアする

ローカルのデータをクリアするには、一度サーバを止めて、下記のように -c を付けて runserver してください。

$ python manage.py runserver -c

15.7. ローカルへデータをリストアする

ローカルの開発サーバーへデータをリストアする時は、-u パラメーターで remote API の URL を指定するだけです。

$ python manage.py restore_all -n 20090919local -u http://localhost:8080/remote_api

15.8. 自動採番の id について

この方法でリストアする時には、自動採番された id も復元されますので、ReferenceProperty や parent/child の 関係も完全に復元されます。ただし、あるアプリからダンプしたデータを別のアプリにリストアした場合、id の衝突が起る可能性があります。つまり、既存のエンティティは上書きされる可能性があるという事です。

また、新規の app slot 上で自動的に採番される id が、リストアした id と競合を起こす可能性もあります。この場合には競合をさけるために datastore.AllocateIds() を呼ぶ必要があるでしょう。ただし現在のところ、どの id 範囲を allocate するかを完全にコントロールできるわけでは無いので、多くの場合、このタスクは非常に難しいか、不可能な場合さえあります。

今のところの一番単純なワークアラウンドとしては、全てのエンティティを key_name を指定して保存する事です。それを実現するのに kay.models.NamedModel を使う事もできます。この class は create_new_entity() という classmethod があり、ランダム生成された uuid を key_name としてエンティティを作成する事ができます。

どうやら appengine のチームは本格的に別 appid へのリストアをサポートするつもりらしいです。SDK-1.2.8のリリースノートでは他 appid へのリストアに対応と書いてあるので期待しています。

15.9. ダンプやリストアに失敗する場合

ダンプやリストアが失敗する場合には _backup/__init__.py を作り kind 毎に bulkloader の設定をカスタマイズする事で対応します。

15.9.1. 失敗するケース1

リストアする entity が大きいと、api の 1M limit にひっかかって失敗するケースがあります。例えば bbs_image という kind の設定をカスタマイズして、一度に一つの entity のみ送るように設定するには下記のようにします。

_backup/__init__.py:

restore_options = {
  'bbs_image': ['--batch_size=1'],
}

15.9.2. 失敗するケース2

ローカルの開発サーバーからダンプする時に、ローカルの開発サーバーはシングルスレッドなのが原因なのか、よう分らないエラーで失敗する時がありました。試しに下記のように設定してシングルスレッドでダンプするようにしたら成功しました。

_backup/__init__.py:

dump_options = {
  'chat_message': ['--num_threads=1'],
}

他に失敗するケースがあれば、私に教えてください。ここに設定例を加えて行きたいと思います。