Google App Engineで簡単にデータを保存する

 Google App Engine(以下GAE)でデータを永続的に保存したい場合、Google様が誇るDatastoreを用いて保存します。このとき保存したいデータに合わせたModelを書かなければいけません。

class SomeModel(db.Model):
    name = db.StringProperty()
    point = db.IntegerProperty()

こんな感じの。でもGAEで作っているとちょっとした変数をリクエスト間でまたがって保存したいときがたまに出てくる。フラグとか最新リクエストのステータスコードとか。そんなちょこっとしたデータ保存のためにわざわざModelを書くのはめんどい。そう感じたので、Modelを書かずにキーと値だけで保存できるモジュールを作ってみました。コードはGitHubに置いてあるけど、短いので以下のとおり。
http://github.com/yuribossa/TinyStore

from google.appengine.ext import db
 
class TinyStoreModel(db.Expando):
    key_ = db.StringProperty()
 
class TinyStore():
    def write(self, key, value):
        query = db.Query(TinyStoreModel).filter('key_ =', key)
        if query.count():
            query = query.get()
            query.value = value
        else:
            if isinstance(key, (str, unicode)):
                query = TinyStoreModel(key_=key, value=value)
            else:
                return False
        
        query.put()
        return True
    
    def read(self, key):
        query = db.Query(TinyStoreModel).filter('key_ =', key)
        if query.count() == 1:
            query = query.get()
            return query.value
        return None
    
    def check(self, key):
        query = db.Query(TinyStoreModel).filter('key_ =', key)
        if query.count():
            return True
        else:
            return False
    
    def delete(self, key):
        query = db.Query(TinyStoreModel).filter('key_ =', key)
        if query.count():
            query = query.get()
            query.delete()
            return True
        else:
            return False

実際にデータを保存するModelであるTinyStoreModelにはキーの宣言しかされてません。また親クラスがdb.Expandoとなっていて、通常のdb.Modelとは違います。このdb.Expandoはdb.Modelのサブクラスで動的プロパティを使いたい場合に継承します。動的プロパティっていうのは、いろんなデータ型を保存できます。あらかじめデータ型が決まっているわけでなく、Modelの宣言の中ではプロパティ名すらありません。データ型が実行時まで決まらないものを保存する場合に便利なプロパティです。で、今回はキー値に文字列、保存する値はGAEでサポートされているデータ型すべてとしています。使用方法は、まずインスタンスを作成します。

from tiny_store import TinyStore

x = TinyStore()

データを保存したい場合はwrite()を使います。

x.write(u'ももクロブログ最後の投稿者', u'百田夏菜子')

これで'ももクロブログ最後の投稿者'と'百田夏菜子'が関連付けられて保存されます。読み出したいときはread()を使います。

name = x.read(u'ももクロブログ最後の投稿者')

キー値はユニークなので、同名のキーに対してwrite()すると上書きされます。

# '百田夏菜子'が上書きされて'佐々木彩夏'になる。
x.write(u'ももクロブログ最後の投稿者', u'佐々木彩夏')

ひとつのエンティティに対してどんなデータ型の値も保存できます。

# 文字列型を保存しているエンティティに整数も保存できる
x.write(u'ももクロブログ最後の投稿者', 100)

エンティティが存在するか判別したいときはcheck()を使用します。

x.check(u'ももクロブログ最後の投稿者')

エンティティ自体を削除したいときはdelete()を使用します。

x.delete(u'ももクロブログ最後の投稿者')

こんな感じでModelを意識せずに簡単にデータを保存できます。これはいわゆるKey-Value Storeになるんでしょうか。