次は、いよいよGoogle App Engineのデータベースを利用します。

Googleデータベースの利用

Google App EngineでPythonを使ってみる」からの続きです。
前回、ユーザーの情報を格納するPersonクラスを作成しました。
Google App Engine上でのPythonプログラミングの手順が理解できたと思います。

今回、Google App Engineの醍醐味であるデータベースへの保存を体験します。

新規アカウント登録APIを作る

いつまでも、ユーザー情報をプログラミング中にハードコーディングするのは変なので、新規アカウント登録機能を追加します。その機能で、ユーザー情報を初期化して、データベースに保存するところまでをやってみます。

まず、新規アカウントの登録をHTTPのPOSTメソッドで受け付けるハンドラークラスを作ってみます。
POSTメソッドとは、Webページの入力フォームでOKしたときに、入力データをサーバに送信するときに良く利用される送信方法です。複雑なデータをサーバに送信することができます。一方、シンプルなデータの場合は、URL上に値を?name=valueのように含ませて送るGETメソッドを使います。

HTTPのリクエストを受け付けるハンドラークラスの名前をCreateAccountとします。
実は、CreateAccountという名称、Googleの新規アカウント受付で使われている登録APIの名前を真似しました。
さらに、このCreateAccountクラスの実装は、SDKに入っているdemos/guestbookのGuestbookクラスを参考にしています。
作成したクラスは以下のようになりました。
# 新規アカウント登録API
class CreateAccount(webapp.RequestHandler):
  def post(self):
    # 新規アカウント入力フォームのnameを取り出す
    name = self.request.get('name')

    # 新しいPersonオブジェクトの生成
    person = Person(name=name)
    person.balance = 200

    # データベースへの登録
    # dev_appserver.pyによってローカルのユーザディレクトリ以下の
    # Local Settings\Temp\dev_appserver.datastoreに保存される
    person.put()

    # メインページへリダイレクト
    self.redirect('/')

このクラスは、webapp.RequestHandlerというGoogleのWebアプリケーションフレームワークのクラスを継承しています。
Webアプリケーションフレームワークは、Webアプリケーションのプログラミングで必要となる機能があらかじめコーディングされていて、プログラマーが下準備にとらわれることなく目的のプログラミングに注力できるような環境を提供します。
ですので、ここは、あまり考えず、demos/guestbookを参考に、postというメソッドを書き換えてみます。
フォームからnameを取り出し、そのnameで、Personオブジェクトを生成、そして、データベースへ保存します。
person.put()、この行がユーザー情報をデータベースへ格納している箇所となります。

さて、データベースはどこに保存されているのでしょうか?
google_appengine\dev_appserver.pyを引数なしで起動したときに表示される以下の箇所に書かれています。
 --datastore_path=PATH      Path to use for storing Datastore file stub data.
                            (Default c:\docume~1\admini~1\locals~1\temp\dev_apperver.datastore)

この例(私のPC)では、admini~1となっていますが、SDKを起動しているローカルPCのユーザディレクトリ配下のLocal Settings\Temp\dev_appserver.datastoreがSDKでのデータ保存先となります。
これが、Googleへデプロイ(アップロード)して、利用されると、Googleの巨大なクラウドに保存されるのです。無料で利用できる、その保存可能なサイズが500MBということです。

新規アカウント登録APIの登録

先ほど作ったクラスは、webapp.RequestHandlerクラスを継承して作ったものですが、これだけでは、Web APIとして動作しません。このクラスを動かすためのURLを決めてあげます。main関数を以下のように書き換えます。
MainHandlerの次に、CreateAccountを
def main():
  application = webapp.WSGIApplication([
    ('/', MainHandler),
    ('/CreateAccount',CreateAccount)
    ],debug=True)
  wsgiref.handlers.CGIHandler().run(application)

これにより、http://localhost:8080/CreateAccount というCGIが作成できたことになります。
このCGIは、'name=ユーザー名'というデータがPOSTされると、CreateAccount.postメソッドを実行します。

新規アカウント入力フォームの作成

マニュアルで、http://localhost:8080/CreateAccountへデータをPOSTするのは面倒なので、メインページに、新規アカウント入力フォームを表示するようにします。
まず、入力フォームをHTMLだけで作成してみます。

          <form action="/CreateAccount" method="post">
            <div><input type="text" name="name"></textinput></div>
            <div><input type="submit" value="Create Account"></div>
          </form>

このフォームもdemos/guestbookの真似です。divとか使ってますが、今後、CSSなどでデザインするときには、divにid属性やclass属性を追加することになります。
このフォームを表示するために、MainHandlerのgetメソッドを以下のように書き換えます。
class MainHandler(webapp.RequestHandler):

  def get(self):
    self.response.out.write("<html></body>")
    self.response.out.write('Input New Account!<br>')

    # 新規アカウント入力フォーム
    self.response.out.write("""
          <form action="/CreateAccount" method="post">
            <div><input type="text" name="name"></div>
            <div><input type="submit" value="Create Account"></div>
          </form>""")

    # 既存アカウントの出力    
    self.response.out.write('Now Account List<br>')
    persons = db.GqlQuery("SELECT * "
                          "FROM Person ")
    for person in persons:
      self.response.out.write(self.balanceHTML(person))

    self.response.out.write("</body></html>")
    
  def balanceHTML(self,person):
    html = 'name:' + person.name + "/"
    html += 'balance:' + str(person.balance)
    html += 'date:' + person.date.ctime()
    html += "<br>"
    return html

balanceHTML(self,person)は、前回のままで、ユーザーの残高をHTML化する関数です。
入力フォームは、self.response.out.writeを使ってそのまま出力しています。
フォームの後ろに、これまで登録されたアカウントのリストを表示するようにしました。
ここが、データベースからデータを取り出している箇所です。
db.GqlQueryという関数を使ってSQL文でデータクラスのオブジェクトを取得しています。
データベースは、ファイルベースで保存されているので、dev_appserver.pyを再起動しても、データは残っています。
データを削除したいときは、--clear_datastoreオプションをつけて
 > cd "C:\Program Files\Google"
 > google_engine\dev_appserver.py --clear_datastore helloworld

のようにSDKのサーバを起動するとまっさらな状態から始めることができます。
http://localhost:8080/ でアクセスして動作を確認してみてください。

Wiki内検索

お知らせ

Happyブログパーツに、Googl App Engineのセットアップ方法を記述中です。
Hello worldの表示までできました。
Hello worldをサンドボックスとして、pythonプログラミングに慣れる方法を記述中です。

どなたでも編集できます