2011年2月9日水曜日

google app engine のデータストアをバックアップ、リストア(bulk loader ツール)

今日はGAEのデータストアのバックアップとリストアに挑戦。
(bulk loader ツール)

まずここを参照。
「データのアップロードとダウンロード」
http://code.google.com/intl/ja/appengine/docs/python/tools/uploadingdata.html

ふむふむ。
まずRemote API を有効にする必要があるとの事。
app.yamlの末尾に以下を追加
builtins:
- remote_api: on
- datastore_admin: on

・・・「datastore_admin: on」はついで。ダッシュボード側のデータストアのコピー操作ができるようになるおまじない。これは今回は使わないけどおまけw

で、コマンドプロンプトをだして(自分、Win環境ですが何か!?)

appcfg.py update D:\gaestudy\hogehoge

これは難なく成功。あ、ちなみに今回のappidは「hogehoge」
で次はと・・・
まずダウンロードしてみるか。ドキュメントにあるようにやってみる。
appcfg.py download_data --application=hogehoge --kind=Greeting --url=http://hogehoge.appspot.com/_ah/remote_api --filename=D:\gaestudy\hogehoge\bbbbb.dump

あ、ちなみに今回抽出したkind(テーブル?)はGreetingって名前。ま、掲示板。
bbbbb.dumpってファイルに出力。
できた。中身みたら、バイナリデータっぽい。
意外に簡単だなぁ

次アップロードいってみよう。まずダッシュボード側で既存のレコードを削除
で、ドキュメントにあるようにやってみる

appcfg.py upload_data --application=hogehoge --kind=Greeting --filename=D:\gaestudy\hogehoge\bbbbb.dump D:\gaestudy\hogehoge

ぬぉ、エラー!!!
Application: hogehoge; version: 1.
Uploading data records.
[INFO    ] Logging to bulkloader-log-20110210.105147
[INFO    ] Throttling transfers:
[INFO    ] Bandwidth: 250000 bytes/second
[INFO    ] HTTP connections: 8/second
[INFO    ] Entities inserted/fetched/modified: 20/second
[INFO    ] Batch Size: 10
[INFO    ] Opening database: bulkloader-progress-20110210.105147.sql3
[INFO    ] Connecting to hogehoge.appspot.com/_ah/remote_api(/.*)
[ERROR   ] Exception during authentication
Traceback (most recent call last):
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\bulkloader.py", line 3175, in Run
    self.request_manager.Authenticate()
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\bulkloader.py", line 1187, in Authenticate
    remote_api_stub.MaybeInvokeAuthentication()
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\remote_api\remote_api_stub.py", line 540, in MaybeInvokeAuthentication
    datastore_stub._server.Send(datastore_stub._path, payload=None)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\appengine_rpc.py", line 341, in Send
    f = self.opener.open(req)
  File "C:\Python25\lib\urllib2.py", line 387, in open
    response = meth(req, response)
  File "C:\Python25\lib\urllib2.py", line 498, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python25\lib\urllib2.py", line 425, in error
    return self._call_chain(*args)
  File "C:\Python25\lib\urllib2.py", line 360, in _call_chain
    result = func(*args)
  File "C:\Python25\lib\urllib2.py", line 506, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 404: Not Found
[INFO    ] Authentication Failed

「HTTPError: HTTP Error 404: Not Found」?

アップ先が見つからないっぽい?よくわからないので、まずappcfg.py自体の説明を読んでみる。
http://code.google.com/intl/ja/appengine/docs/python/tools/uploadinganapp.html

appcfg.py help <action>
#指定されたアクションに関するヘルプ メッセージを出力し、終了します。

というわけで、まぁhelpを見てみよう

appcfg.py help upload_data

で、出た結果がこれ

>appcfg.py help upload_data
Usage: appcfg.py [options] upload_data >directory<

Upload data records to datastore.

The 'upload_data' command translates input records into datastore entities and
uploads them into your application's datastore.

Options:
  -h, --help            Show the help message and exit.
  -q, --quiet           Print errors only.
  -v, --verbose         Print info level logs.
  --noisy               Print all logs.
  -s SERVER, --server=SERVER
                        The server to connect to.
  --insecure            Use HTTP when communicating with the server.
  -e EMAIL, --email=EMAIL
                        The username to use. Will prompt if omitted.
  -H HOST, --host=HOST  Overrides the Host header sent with all RPCs.
  --no_cookies          Do not save authentication cookies to local disk.
  --passin              Read the login password from stdin.
  -A APP_ID, --application=APP_ID
                        Override application from app.yaml file.
  -V VERSION, --version=VERSION
                        Override (major) version from app.yaml file.
  --filename=FILENAME   The name of the file containing the input data.
                        (Required)
  --kind=KIND           The kind of the entities to store.
  --url=URL             The location of the remote_api endpoint.
  --num_threads=NUM_THREADS
                        Number of threads to upload records with.
  --batch_size=BATCH_SIZE
                        Number of records to post in each request.
  --bandwidth_limit=BANDWIDTH_LIMIT
                        The maximum bytes/second bandwidth for transfers.
  --rps_limit=RPS_LIMIT
                        The maximum records/second for transfers.
  --http_limit=HTTP_LIMIT
                        The maximum requests/second for transfers.
  --db_filename=DB_FILENAME
                        Name of the progress database file.
  --auth_domain=AUTH_DOMAIN
                        The name of the authorization domain to use.
  --log_file=LOG_FILE   File to write bulkloader logs.  If not supplied then a
                        new log file will be created, named: bulkloader-log-
                        TIMESTAMP.
  --dry_run             Do not execute any remote_api calls
  --namespace=NAMESPACE
                        Namespace to use when accessing datastore.
  --has_header          Whether the first line of the input file should be
                        skipped
  --loader_opts=LOADER_OPTS
                        A string to pass to the Loader.initialize method.
  --config_file=CONFIG_FILE
                        Name of the configuration file.

なるほど。とりあえず「--noisy」をつけて全ログを出してみるか

appcfg.py upload_data --noisy --application=hogehoge --kind=Greeting --filename=D:\gaestudy\hogehoge\bbbbb.dump D:\gaestudy\hogehoge

で出た結果↓

Application: hogehoge; version: 1.
Uploading data records.
[INFO    ] Logging to bulkloader-log-20110210.105736
[INFO    ] Throttling transfers:
[INFO    ] Bandwidth: 250000 bytes/second
[INFO    ] HTTP connections: 8/second
[INFO    ] Entities inserted/fetched/modified: 20/second
[INFO    ] Batch Size: 10
[INFO    ] Opening database: bulkloader-progress-20110210.105736.sql3
[DEBUG   ] [Thread-1] RestoreThread: started
[DEBUG   ] [Thread-1] RestoreThread: exiting
[DEBUG   ] [Thread-2] RestoreThread: started
[DEBUG   ] [Thread-2] RestoreThread: exiting
[DEBUG   ] [Thread-3] WorkerThread: started
[DEBUG   ] [Thread-4] WorkerThread: started
[DEBUG   ] [Thread-5] WorkerThread: started
[DEBUG   ] [Thread-6] WorkerThread: started
[DEBUG   ] [Thread-7] WorkerThread: started
[DEBUG   ] [Thread-8] WorkerThread: started
[DEBUG   ] [Thread-9] WorkerThread: started
[DEBUG   ] [Thread-10] WorkerThread: started
[DEBUG   ] [Thread-11] WorkerThread: started
[DEBUG   ] [Thread-12] WorkerThread: started
[DEBUG   ] Configuring remote_api. url_path = /_ah/remote_api(/.*), servername = hogehoge.appspot.com
[DEBUG   ] Bulkloader using app_id: hogehoge
[INFO    ] Connecting to hogehoge.appspot.com/_ah/remote_api(/.*)
[ERROR   ] Exception during authentication
Traceback (most recent call last):
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\bulkloader.py", line 3175, in Run
    self.request_manager.Authenticate()
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\bulkloader.py", line 1187, in Authenticate
    remote_api_stub.MaybeInvokeAuthentication()
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\remote_api\remote_api_stub.py", line 540, in MaybeInvokeAuthentication
    datastore_stub._server.Send(datastore_stub._path, payload=None)
  File "C:\Program Files\Google\google_appengine\google\appengine\tools\appengine_rpc.py", line 341, in Send
    f = self.opener.open(req)
  File "C:\Python25\lib\urllib2.py", line 387, in open
    response = meth(req, response)
  File "C:\Python25\lib\urllib2.py", line 498, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python25\lib\urllib2.py", line 425, in error
    return self._call_chain(*args)
  File "C:\Python25\lib\urllib2.py", line 360, in _call_chain
    result = func(*args)
  File "C:\Python25\lib\urllib2.py", line 506, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 404: Not Found
[INFO    ] Authentication Failed

なんか文字を連結してるっぽいところがある
[DEBUG ] Configuring remote_api. url_path = /_ah/remote_api(/.*), servername = hogehoge.appspot.com

?urlのpathなのにhttp://が入ってねーな。まぁそうはいっても中で補完してるよね、と思いたいが、んー、怪しい。
そういえば、さっきのコマンドにurl直接指定出来なかったっけ。もう一回help見てみる。
--url=URL The location of the remote_api endpoint.

あったあった。要するにurlを引数から作ってるなら、最初から絶対パスを渡してやれば間違いないのでは。
という事で付け足してみる。

appcfg.py upload_data --noisy --application=hogehoge --kind=Greeting --filename=D:\gaestudy\hogehoge\bbbbb.dump --url=http://hogehoge.appspot.com/_ah/remote_api D:\gaestudy\hogehoge

おおおお、いった。成功ログ↓

Application: hogehoge; version: 1.
Uploading data records.
[INFO    ] Logging to bulkloader-log-20110210.110730
[INFO    ] Throttling transfers:
[INFO    ] Bandwidth: 250000 bytes/second
[INFO    ] HTTP connections: 8/second
[INFO    ] Entities inserted/fetched/modified: 20/second
[INFO    ] Batch Size: 10
[INFO    ] Opening database: bulkloader-progress-20110210.110730.sql3
[DEBUG   ] [Thread-1] RestoreThread: started
[DEBUG   ] [Thread-1] RestoreThread: exiting
[DEBUG   ] [Thread-2] RestoreThread: started
[DEBUG   ] [Thread-2] RestoreThread: exiting
[DEBUG   ] [Thread-3] WorkerThread: started
[DEBUG   ] [Thread-4] WorkerThread: started
[DEBUG   ] [Thread-5] WorkerThread: started
[DEBUG   ] [Thread-6] WorkerThread: started
[DEBUG   ] [Thread-7] WorkerThread: started
[DEBUG   ] [Thread-8] WorkerThread: started
[DEBUG   ] [Thread-9] WorkerThread: started
[DEBUG   ] [Thread-10] WorkerThread: started
[DEBUG   ] [Thread-11] WorkerThread: started
[DEBUG   ] [Thread-12] WorkerThread: started
[DEBUG   ] Configuring remote_api. url_path = /_ah/remote_api, servername = hogehoge.appspot.com
[DEBUG   ] Bulkloader using app_id: hogehoge
[INFO    ] Connecting to hogehoge.appspot.com/_ah/remote_api
[DEBUG   ] [Thread-13] ProgressTrackerThread: started
[DEBUG   ] [Thread-14] DataSourceThread: started
[INFO    ] Starting import; maximum 10 entities per post
[DEBUG   ] [Thread-14] DataSourceThread: exiting
[DEBUG   ] Waiting for worker threads to finish...
[DEBUG   ] [Thread-3] Got work item [1-7]
[DEBUG   ] [Thread-3] [1-7] Transferred 7 entities in 8.0 seconds
.[DEBUG   ] [Thread-5] WorkerThread: exiting
[DEBUG   ] [Thread-6] WorkerThread: exiting
[DEBUG   ] [Thread-7] WorkerThread: exiting
[DEBUG   ] [Thread-8] WorkerThread: exiting
[DEBUG   ] [Thread-9] WorkerThread: exiting
[DEBUG   ] [Thread-10] WorkerThread: exiting
[DEBUG   ] [Thread-11] WorkerThread: exiting
[DEBUG   ] [Thread-12] WorkerThread: exiting
[DEBUG   ] [Thread-4] WorkerThread: exiting
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] [Thread-3] WorkerThread: exiting
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit
[DEBUG   ] Waiting for Anonymous_WorkerThread to exit

[DEBUG   ] Waiting for progress_thread to terminate...
[DEBUG   ] [Thread-13] ProgressTrackerThread: exiting
[DEBUG   ] ... done.
[INFO    ] 7 entites total, 0 previously transferred
[INFO    ] 7 entities (6381 bytes) transferred in 9.8 seconds
[INFO    ] All entities successfully transferred

なんか時間かかったな。
GAEのdashboardに入ってDatastore Viewerの該当kindを見てみると、ちゃんと入ってる。

ちなみに、既存のデータは「ID/Name」をキーにして上書きされた。

dashboardで新しいレコードを入れてからアップロードしてみると、新しいレコードは消えない事を確認。

あと、既存の情報(アップロードファイルに含まれるレコード)を、dashboard側を変更してからアップしたら、変更したレコードはファイルの情報で上書きされた。

ただ、変更や新規がある時は解析?か何かに若干時間がかかるのか、たまに

HTTPError: HTTP Error 500: Internal Server Error

が出る事があったが、もう一度やるとうまくいった。まぁタイミングかな。気にするほどではないか。

ちなみにローカル環境にアップロードする場合はurlを変えるだけでいけた。

appcfg.py upload_data --noisy --application=hogehoge --kind=Greeting --filename=D:\gaestudy\hogehoge\bbbbb.dump --url=http://localhost:8080/_ah/remote_api D:\gaestudy\hogehoge

もちろん「Run」状態にして、urlが生きていないと入らない。
Development(SDK) Console で確認できる

http://localhost:8080/_ah/admin/

これでインポートとエクスポートは簡単になったなー。
次回は「Bulk Loader」を使ってcsvからのインポートやcsvでのエクスポートに挑戦予定。
これができるとcsv上で編集や追加した上で反映させられるので、かなり実用的になる。

免責
この記事やプログラムによって生じた事故・損害などは一切保証致しません。ご自身の責任でご使用ください。

子育てブログ「おとう日記」はじめました。
興味ある方、是非ご覧下さい!
おとう日記

コピペプログラマの倉庫を作りました。
サンプルプログラムなど置いておきますのでお立ち寄り下さい。
コピペプログラマ倉庫


良ければ↓投票お願いします↓ m(._.)m ペコッ
人気ブログランキングへ

0 件のコメント:

コメントを投稿