スキップしてメイン コンテンツに移動

[Python][Google App Engine]db.Modelのput/getで勝手にmemcacheを使うよう拡張してみた

GAEを使う必ずみんな意識するのがDataStoreへのアクセスをいかに減らすか。
それすなわちキャッシュの使い方なり!

と考えているわけですが、やることなんて以下の2点だと思います。

・Model.put()するときにはmemcache.set()しろ
・Model.get()するまえにmemcache.get()しろ

そこで、db.Modelを拡張しました。
まず、ModelAbsというdb.Modelを継承した中間のクラスを作って。

==========
class ModelAbs(db.Model):
    def put_with_cache(self,key_name):
        self.put()
        memcache.set(key=key_name,value=self)
        return self.key()
    @classmethod
    def get_with_cache(cls,key_names,**kwargs):
        if isinstance(key_names,list) == False:
            key_names = [str(key_names)]
        models = list()
        for key_name in key_names:
            ent = memcache.get(key=key_name)
            if ent == None:
                ent = cls.get_by_key_name(key_names=key_name)
                memcache.set(key=key_name,value=ent)
            models.append(ent)
        if len(key_names) > 1:
            return models
        else:
            return models[0]
==========

そのModelAbsを継承したエンティティのクラスを作りました。

==========
class SPOTS(ModelAbs):
    update = db.DateTimeProperty(required=True)
    USDJPY = db.StringProperty(multiline=False)
    EURJPY = db.StringProperty(multiline=False)
    EURUSD = db.StringProperty(multiline=False)
    AUDJPY = db.StringProperty(multiline=False)
    GBPJPY = db.StringProperty(multiline=False)
    NZDJPY = db.StringProperty(multiline=False)
    CADJPY = db.StringProperty(multiline=False)
    CHFJPY = db.StringProperty(multiline=False)
    HKDJPY = db.StringProperty(multiline=False)
    GBPUSD = db.StringProperty(multiline=False)
    USDCHF = db.StringProperty(multiline=False)
    ZARJPY = db.StringProperty(multiline=False)
==========

基本的にdb.Modelのkey_nameでの読み書きになります。

==========
class MainHandler(webapp.RequestHandler):
    def get(self):
        now = datetime.datetime.now() + datetime.timedelta(hours=9)
        str_now = datetime.datetime.strftime(now,'%Y%m%d%H%M')
        key = 'SPOTS:'+str_now
        rate = commons.GetCurrentRate()
        spot = models.SPOTS(key_name=key,
                            update=now,
                            USDJPY = rate['USDJPY'],
                            EURJPY = rate['EURJPY'],
                            EURUSD = rate['EURUSD'],
                            AUDJPY = rate['AUDJPY'],
                            GBPJPY = rate['GBPJPY'],
                            NZDJPY = rate['NZDJPY'],
                            CADJPY = rate['CADJPY'],
                            CHFJPY = rate['CHFJPY'],
                            HKDJPY = rate['HKDJPY'],
                            GBPUSD = rate['GBPUSD'],
                            USDCHF = rate['USDCHF'],
                            ZARJPY = rate['ZARJPY'])
        ds_key = spot.put_with_cache(key_name=key)
        entity = spot.get_with_cache(key_names=key)
        self.response.out.write(str(key)+'<改行>')
        self.response.out.write(str(ds_key)+'<改行>')
        self.response.out.write(str(entity.key())+'<改行>')
        self.response.out.write(str(rate))
==========

これでたくさんのif文を書かずにシンプルにキャッシュが利用出来るようになりました。

コメント

このブログの人気の投稿

[Mac]Time Machineのバックアップ先をWindows共有フォルダに設定する

こんばんは。もっくんです。 2台あったWindowsのデスクトップを1台にまとめるついでに、ずっと放置していたMacのバックアップ環境を構築してみました。Finderでコピペするだけでいいんですが、どうせなら「Mac全体を自動的にバックアップします。」という謳い文句のTime Machineを使いたい。 Apple純正のTime CapsuleやUSBの外付けHDDという手もあったんですが、ノートの機動性を落としたくなかったし、なによりタダでできそうなWindows共有フォルダにネットワーク越しにバックアップする方法を取ることにしました。 実際の流れは下記のようになります。 ネットワーク共有フォルダを作成する 空のディスクイメージを作成する ネットワーク共有フォルダにディスクイメージをコピーする ネットワーク共有フォルダのディスクイメージをマウントする マウントしたディスクイメージをTime Machineのバックアップ先に指定する 1.ネットワーク共有フォルダを作成する この手順はそこまで面倒ではないので、簡単な手順だけ。 Windows全体の設定でファイル共有を有効にする(Windowsで作業) Macと共有(Macから見えるように)したいフォルダを作成する(Windowsで作業) 共有したいフォルダに共有設定をする(Windowsで作業) 共有フォルダに接続(Macで作業) 詳細はこちらの記事が画像付きでわかりやすい。 http://blog.goo.ne.jp/beosound/e/7d6d0d0a8f76035f880001eda06c4247 2.空のディスクイメージを作成する いわばこのディスクイメージがバックアップ先のHDDの代わりとなる。 アプリケーション > ユーティリティ > ディスクユーティリティを起動 画面上部の ファイル > 新規 > 空のディスクイメージをクリック 設定画面の各欄は以下のように設定 名前: TimeMachineVolume(なんでもよい) 保存先: デスクトップ(ローカルのわかりやすい場所) ボリューム名: TimeMachineVolume(なんでもよい) ボリュームサイズ: カスタム ...

[Python]個別銘柄の時系列データをGoogle Financeから取得するプログラム

今日書いたのはこれ。 Google Finance から証券コードを指定して日別の価格情報を取得するプログラムです。 米国市場に上場している銘柄であればCSVでダウンロードでますが、日本の銘柄はできなかったので作りました。 多くの人はYahoo!Japanから取得しているようなので、あえてGoogle Financeから取得してみました。 ちなみに使えるのは東証に上場している銘柄のみです。(おそらく) このプログラムと 日経225構成銘柄一覧取得プログラム を組み合わせれば、日経225構成銘柄の時系列データが取得できてしまいます。 #!/usr/local/bin/python # -*- coding:utf-8 -*- from BeautifulSoup import BeautifulSoup import urllib2,re,datetime,sys class googleFinance2CSV(object): def __init__(self,ticker): ''' 引数で渡されたticker(=証券コード)の時系列データを Google Financeから取得してCSV形式で保持する CSVの列は'Date','Open','High','Low','Close','Volume' ''' self.ticker = ticker self.url = 'http://www.google.com/finance/historical?q=%s&num=200' % str(self.ticker) self.csv = str() soup = BeautifulSoup(urllib2.urlopen(self.url)) tablesoup = soup.find("table", {"class":"gf-table historical_price"}) for trsoup in tablesoup.findAll("tr...

[Python]日経225構成銘柄の一覧を取得するプログラム

今日書いたのはこれ。 日経225の構成銘柄が変更になるといちいち変更が面倒なので作りました。 コメントに書いてある機能しかありませんが、簡単でよし。 ご参考になれば。 #!/usr/local/bin/python # -*- coding:utf-8 -*- from BeautifulSoup import BeautifulSoup import urllib2,re class Nikkei225Profile(object): def __init__(self): ''' 日経新聞のサイトから日経225の構成銘柄の証券コードと証券名称を取得 ''' self.url = 'http://www3.nikkei.co.jp/nkave/about/225_list.cfm' self.profile = dict() soup = BeautifulSoup(urllib2.urlopen(self.url)) tablesoup = soup.find("table") rows = tablesoup.findAll('tr',{'bgcolor':'#FFF5DE'}) rows += tablesoup.findAll('tr',{'bgcolor':'#F0E7D1'}) for row in rows: row_list = [cell.find(text=True) for cell in row.findAll('td')] self.profile[row_list[0]] = row_list[1] def getprofile(self,googlestyle=False): ''' 日経225の証券コードと証券名称をdict()で返す ...