月別アーカイブ: 2014年11月

GAE(Google App Engine)pythonのNDBでデータの有る無しを確認してから取り出す。

GAEのデータストアNDBからデータを取り出す時にはまった。
日付データと、いくつかの文字列型のデータを収めるデータ型のクラスがあって、文字列は時々からの場合がある。
これをデータが空でないエンティティだけを取り出して、日付データでソートする、というのをやりたかったんだけど、どうしてもエラーが出てしまう。
どうも、このデータ型のクラスだけでは、希望のデータ取り出し方法はできないようで、結局、もう一つBooleanProperty型のプロパティを加えてあげることで解決した。

BooleanPropertyはTrueかFalseを収めることができる型で、データを入れるときにデータがあれば、BooleanPropertyをTrueにしておく。すると、取り出すときに、BooleanPropertyがTrueの物をフィルタリングすることで、あっけなく希望通りのデータ取り出しが出来た。

ネクサス7をアンドロイド5にアップグレードしたら異様に遅くなって、その後解決したこととか

少し前の話だけど、2012年にGoogle Playで購入したNexus7(32GB)に、今月(2014年11月)になってOSのAndroid5へのアップデートのお知らせが来ていた。迷うことなくすぐにアップグレードしたんだけど、アップグレード後にネクサス7の動作の全てが異様に遅くなった。どのくらい遅くなったかというと、我慢の限界を越えて、タブレットをパキンと真っ二つに割ってしまいたくなるくらい遅くなった。

電池の持ちを良くするために、普段はいつも飛行機搭乗モードにして、wifiだけONにして、ブラウザとアマゾンキンドル、他ごく一部のアプリだけ使っている。もしかしたらそれが何か影響してるのかと思い、飛行機モードを解除しても治らず。とてもまともに使える状態ではないので、ネットで調べたら同じような人がたくさんいて、対策法が1つ紹介されていた、これで治らない人もいるらしいが、私の場合は完璧に解決して、むしろアップデート前より早くなったんじゃないかというくらい快適になった。

方法は以下。

電源OFFにする。

電源ボタンと、ボリュームダウンボタンを同時に長押し

画面の左下に小さな文字でいくつか選択肢メニューが出てくるので、
「recovery mode」を選択して決定(選択は音量ボタン、決定は電源ボタン)

小さなAndroidロボットが倒れて「!」みたいなマークが出てくるので、そこで
電源ボタンとボリュームアップボタンを同時に押して、電源ボタンだけ離す。

またいくつかメニューが出てくるので、「wipe the cache partition」を選択して決定。

ほんの数秒で、キャッシュクリアが完了と英語で表示(~complete)と出るので
「reboot system now」を選択して、再起動。

これをやっても再起動後直後は、対策する前と全く同じで、物凄く動作が遅いんだけど
しばらくいじっていると、まず、ブラウザ表示がグングン早くなってきて、アプリも最初は異様に遅かったのが、何回かいじっているとだんだん早くなってきてしばらくすると違和感なく動くようになりました。しばらくというのは、具体的には20分か30分。対策前は、同じ時間いじってもずっと遅いままだったので、この対策で解決したっぽい。たぶん裏でいろいろ動いてるんだろうけど、何が起きてるのかは謎。取り敢えず無事に動くようになって良かった。ネクサス7には現状で何も不満はないので、5,6年は普通に使うつもり。

GAE(Google App Engine)pythonのNDBで特定のデータを消す方法

最近、GAEのNDBをいじっていて、わからないことが次々に出てくるんだけど、ネットでいろいろ調べていると、stackoverflowって海外のサイトと、公式のドキュメント、この2つが圧倒的に役に立つ。たまに英語のニュアンスがわからないくて、日本語のみで検索することがあるけど、情報量が違いすぎて、英語ネイティブとの差は大きいなと感じる。

で、特定のデータを消す方法だけど、NDBでは消したいデータのキーを取り出してから消去する、らしくて
X.key.delete()
みたいに書くらしい。

特定の条件に当てはまるデータを消したい場合は、delete_multiを使うといいらしくて

q1 = A.query()
q2 = q1.filter( >=を使ったフィルター ) # Filter
q3 = q2.filter( <=を使ったフィルター ) # Filter ndb.delete_multi(q3.fetch(keys_only=True)) みたいにしたら簡単に消したいデータだけ消すことができた。 keys_only=True というのは、fetchのオプションで、keys_only=Trueとすると、データ(エンティティ)を返すんではなくて、キーのみを返すらしい。 削除に必要なのはキーだけなので、あとは簡単にndb.delete_multiで一発で消去できる。

GAE(Google App Engine)pythonのNDBで非同期機能を使う

GAE(Google App Engine)のpythonで、データベース(NDB)を使うときに非同期機能を使うとスピードが早くなるらしいので試してみた。

プログラムは全くの素人なので、非同期と、同期だと言葉の感覚的に同期の方が早そうなイメージなんだけど、実際は、非同期の方が早いらしい。これは図の説明を見たらなんとなく理解できた。

で、複数のデータを取得するときに、非同期で取得すると、一個づつ順番にデータを集めるんじゃなくて、一斉に複数の指令を出せるから、並列処理出来て早いということっぽい。

やり方は、幾つかあるようだけど、取り敢えず簡単に出来たのは以下。

「fetch」を「fetch_async」に置き換えて、「get_result()」で結果を受け取る。

A_future=B.fetch_async
C_future=D.fetch_async
E_future=F.fetch_async

A = A_future.get_result()
C = C_future.get_result()
E = E_future.get_result()

取り敢えずこんな感じで上手く言った。非同期で並列処理されているかどうかを確認するには、同じくGAE内で用意されている「Appstats」を使うとグラフで簡単にチェックできる。「Appstats」を使う設定は簡単で10分くらいでできる。これはめちゃくちゃ便利。

マニュアルを見ると、asyncの次にTaskletsというのが紹介されていて、yieldとか、イテレーターとかジェネレーターとか調べてて、まだイマイチ理解できていない状態。

最近は、ネットにわかりやすい情報がたくさんあるから、素人でもプログラムの勉強がし易いけど、そうなると、もうソフトの世界より、小型のドローンを中国でバンバン作っていたりするように、ハードの世界で成功する人が増えてくるような気がなんとなくする。

GAE(Google app engine python)でデプロイに失敗しError 409が出た時の解決法

以前もデプロイに失敗して以下のようなエラーが出たことがある。

Error 409: — begin server output —
Another transaction by user (ユーザー名) is already in progress for app: (アプリ名), version: 1. That user can undo the transaction with “appcfg rollback”.

これはデプロイの途中で何かあってエラーが出たという意味らしく、元の状態に戻すためにはコマンドプロンプトからコマンドを打ち込む必要がある。

前回は、ネットで調べてすぐ解決したんだけど、今回はなぜか何度やっても解決しない。原因は、Google app engineを置いている場所と、アプリを置いているフォルダを別の場所においていたからっぽい。

結論を書くと以下のようにしたら解決した。

まず、google_appengineのフォルダ上にマウスポインタを置いて、SHIFTを押しながら右クリック

すると開いたウィンドウ内に「コマンド ウィンドウをココで開く」があるのでクリック。

すると、GAE(Google app engine python)までのパスがすでに表示された状態でコマンドプロンプトが開くので

「python appcfg.py rollback ここにアプリのパスを書く」をコピペしてエンターを押せばOK

アプリのパスは、アプリのフォルダ内を表示させている状態で、フォルダ上部にあるパンくずリスト上で右クリックしてアドレスをコピーで取得できる。

また次回エラーが出た時に時間を無駄にしないように半分自分のためにここにメモしておく。