ローカル開発中、index.yamlの不要なインデックス設定を削除しても復活してしまう場合
datastoreのModelクラスを何度もリファクタしながらローカル開発サーバでテストしていると、index.yamlに、不要なインデックス設定が残ったままになってしまう。
これをきれいにするため、index.yamlの中身を全削除してから実行すると、ローカル開発サーバが、インデックスが必要になった時に自動的にindex.yamlに設定を追加してくれる。
これはとても便利なのだが、もう使っていないはずのインデックス設定が復活してしまうこともある。
これは、いずれかの*.pycに、リファクタ前のプログラムが残ってしまっているのが原因。
ソースコード中の*.pycを全削除して、index.yamlの中身を全削除、そのうえで実行すると万全。
$.Deferredを使って、一定間隔でスリープしながらループする
まずはSleepメソッドを自作する。
function Sleep(msec) { var d = $.Deferred(); setTimeout(function() { d.resolve(); }, msec); return d.promise(); }
繰り返したい処理の本体の実装。こちらも、Deferredを返すようにしておく。
function MyFunc(cnt) { var d = $.Deferred(); $("#divProgress").append("<p>in MyFunc() " + cnt + "</p>"); d.resolve(); return d.promise(); };
で、これをループで呼ぶ。ここでは10回呼ぶようにしてみる。
function() { var counter = [1,2,3,4,5,6,7,8,9,10]; var d = (new $.Deferred()).resolve(); $.each(counter, function(i, value) { d = d .then(function() { return MyFunc(value);}) .then(function() { return Sleep(1000);}); }); }
ポイントは、ループ開始前にDeferredオブジェクトをresolveしておき、それにつなげてthen, then…とやること。各functionの戻り値として、Deferredオブジェクトをリターンしまくること。
サーバ上のdatastoreをローカル開発サーバにリストアする
サーバのデータをローカル開発サーバ上にリストアする方法。
自身のアプリケーションIDを APP_ID とします。
appcfg.py download_data --application=`APP_ID` --url=http://APP_ID.appspot.com/_ah/remote_api --filename=hoge.dump --email=Googleアカウントのメールアドレス
これで、サーバ側のデータが hoge.dump というファイル名で保存されます。
上記例では、全カインドをダウンロードしますが、
--kind=カインド名
のオプションを付与する事により、指定したカインドだけをダウンロードできます。
ここでポイントは、--application=に指定するAPP_IDを、バッククオートで囲むこと。APP_IDに記号が含まれている場合、バッククオートで囲まないと、次のようなエラーになります。
google.appengine.api.datastore\erros.BadRequestError: app s~APP_ID cannot access app APP_ID's data
次に、ダウンロードしたものを、ローカルにリストアします。
ローカル開発サーバを起動した状態としたうえで、次のコマンドでリストアを実行。
appcfg.py upload_data --application=dev~APP_ID --url=http://localhost:ポート番号/_ah/remote_api --filename=hoge.dump --email=Googleアカウントのメールアドレス
ここでのポイントは2つ。
1つめは、ポート番号はAdmin Portではなく、通常のアプリケーションのポートのほうであるということ。
2つめは、applicationIDの指定の仕方。頭に"dev~"を付与することと、ダウンロードの時とは違い、APP_IDに記号が含まれていても、バッククオートで囲まずともエラーにはなりませんでした。
ndbのquery結果の件数を取得する方法
自分の中でごっちゃになっていたので整理する。
Queryのcount()のリファレンスには、こうある。
This returns the same result as len(q.fetch(limit)) but more efficiently.
query = MyModel.query(条件) cnt = query.count() #OK cnt = len(query) #NG cnt = len(query.fetch()) #OK list = MyModel.query(条件).fetch(keys_only=True) cnt = list.count() #NG cnt = len(list) #OK
queryメソッドの戻り値(Queryオブジェクト)はイテレータではあるがリストではないので、len(query)はできない。
fetchメソッドの戻り値は単なるリストなので、
last_data = list[cnt-1]
みたいなことも出来る。
ローカル開発サーバ起動時に import docker でエラーが発生するようになった(2015/02/26時点)
つい今しがた、1ヶ月ぶりぐらいに、gcloud components update をやったら、ローカル開発サーバが起動しなくなってしまった。
エラーログ
dockerがimportできないよ、と言っている。 dockerが何かわからなかったので軽く調べたところ、最近betaとして公開された、Managed VMs に関連するもののようだ。 dockerがインストールされている事を前提としてしまっているようだ。 いつか修正されるような気はするのだが、とりあえず動くようにするためには、dockerをインストールする必要がある。Running dev_appserver with the following flags:
--skip_sdk_update_check=yes --port=12080 --admin_port=8004 --log_level=debug --datastore_path=/Users/noazoh/develop/app_id/datastore/dev_appserver.datastore Python command: /usr/bin/python2.7 Traceback (most recent call last): File "/Users/noazoh/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/dev_appserver.py", line 83, in_run_file(__file__, globals()) File "/Users/noazoh/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/dev_appserver.py", line 79, in _run_file execfile(_PATHS.script_file(script_name), globals_) File "/Users/noazoh/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 36, in from google.appengine.tools.devappserver2 import dispatcher File "/Users/noazoh/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 29, in from google.appengine.tools.devappserver2 import module File "/Users/noazoh/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 71, in from google.appengine.tools.devappserver2 import vm_runtime_factory File "/Users/noazoh/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/vm_runtime_factory.py", line 25, in from google.appengine.tools.devappserver2 import vm_runtime_proxy File "/Users/noazoh/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/vm_runtime_proxy.py", line 29, in from google.appengine.tools.devappserver2 import log_manager File "/Users/noazoh/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/log_manager.py", line 34, in from google.appengine.tools.docker import containers File "/Users/noazoh/google-cloud-sdk/platform/google_appengine/google/appengine/tools/docker/containers.py", line 47, in import docker ImportError: No module named docker sudo easy_install pipでpipをインストールしてから、sudo pip install docker-pyでdockerをインストールすることにより、エラーが解消しました。 Managed VM の機能を使わないのだから(app.yaml にて、vm: true にはしていない)、dockerをimportしないようにするとか何かしてほしい。
cron.yaml における target の意味
targetに指定するものは、app.yaml における version です。
サーバにリリースはしたが、デフォルトは別のバージョンにしている、などの時に使うもの。