2015年8月14日金曜日

Google App Engine の Cloud Datastore を とにかく簡単に使う

今回、Bitcoin価格評価システムを立ち上げるにあたり、定期的にcoincheck取引所の取引状況を取得するために、Google App Engine を使いました。
もともと、ローカルPC上にPythonで組み上げたシステムがあったので、これを年中動かしっぱなしにできるよう、Google App Engine に移植しました。
Google App Engine は、Java、PHP、Go言語などでも開発できるようですが、Pythonが使い慣れているので、とりあえずPython(バージョン2.7)を使うことにします。

ローカルPC上に作っていたシステムは、Pythonの標準ライブラリに含まれているSQLite3を使っていました。
SQLiteは使い慣れると大変便利で、まるで配列に保存するかのように使えます。取得したデータをとりあえずSQLiteデータベースに放り込んで、重複行を削除したり時間順に並び替えたりという作業のほとんどはSQLiteのコマンドを叩いていました。
App Engine上では、Pythonの標準ライブラリに含まれているSQLite3が使えないので、別の方法を考えなくてはいけません。
App Engineからは、Cloud SQLが使えます。しかし、これには無料枠がありません。それに対して、Cloud Datastoreは、App Engineサービス開始当初から標準でサポートされているデータベースで、無料枠があります。(結局、無料枠は一瞬で使い果たしますが……それについては別の機会に)
本格的なSQLが使いたいわけではなく、ちょっと配列代わりに使いたいだけなので、Cloud Datastoreを使うことにします。

参考までに、今日時点のCloud Datastoreの1日あたりの無料割り当て枠は以下の通りです。
  • 5 万回(読み取り/書き込み/小規模な操作)
  • 1 GB ストレージ
この無料枠につられて、まんまとCloud Datastoreを使う羽目になってしまったのです……

さて、Cloud Datastoreですが、SQLなどのリレーショナルデータベースとはちょっとイメージが違います。同じ「種別」の「エンティティ」の塊をひとつのデータベースとして扱うという感じです。リレーショナルデータベースのイメージからすると、ひとつのデータベースというよりは、テーブルのイメージです。
そして、エンティティ一つ一つが行にあたり、エンティティの「プロパティ」が列(フィールド)にあたります。
Pythonの中では、種別がクラス、エンティティがそのクラスから生成されたオブジェクト、プロパティがそのオブジェクトのメンバー変数で表現されています。
ちょっとややこしくなったので表にまとめます。

リレーショナルデータべーステーブルフィールド(列)
Cloud Datastore種別エンティティプロパティ
Python API での表現クラスオブジェクトメンバー変数
とりあえずこんなイメージで、ざっくり理解しておきます。

とにかくできるだけ簡単にCloud Datastoreを使い始めたいというのであれば、迷わずExpandoクラスを使えばいいでしょう。
# -*- coding: utf-8 -*-
import google.appengine.ext.db as gdb
class Mydb(gdb.Expando):    # Expandoクラスを継承したクラスを作成
    pass
BTCdb = Mydb()    # オブジェクトを生成
BTCdb.data = 34000     # メンバー変数に値を代入
BTCdb.put()     # put()でデータストアに保存
これだけで、テーブルを作って、フィールド(data=34000)を一つ持つ行を保存できました。
Pythonでは、クラス定義の中でオブジェクトのメンバー変数を定義する必要がなく、オブジェクトを生成した後からメンバー変数を作ってやれば、いくらでも増やすことができます。
ですので、Cloud Datastoreのプロパティ(リレーショナルデータベースのフィールド)をメンバー変数を増やすことで、後からいくらでも増やすことができるのです。

データを蓄えるだけなら、一度、put()を実行してしまえば、メンバー変数の中身はデータストアに保存されているので、オブジェクト自体を保持しておく必要はありません。
BTCdb = Mydb()
BTCdb.data = 34000
BTCdb.put()
の部分をどんどん繰り返してやれば、オブジェクトBTCdbが上書きされていくのでどんどんCloud Datastoreにデータが蓄積されていきます。

データの取り出しも簡単で、
q = Mydb.all()
と、するでけです。
for i in q:
    print i.data 
と、実行してやれば、先ほど保存したデータを表示することができます。

また、取り出すだけならGQLというSQLによく似たコマンドがあり、これを叩くことで、リレーショナルデータベースと同じように扱うことができます。

こんな感じで、Cloud Datastoreは配列に保存する感覚でデータを永続的に保存でき、GQLを使ってリレーショナルデータベースのように扱うこともできます。
当初考えていたよりもずっと簡単に使うことができした。

0 件のコメント:

コメントを投稿