Symfoware

Symfowareについての考察blog

Google App Engine Pythonでデバイスメーカーを作成する その2(データ登録編)

前回に引き続き、Google App Engineでアプリケーションを作成してみます。
Google App Engine Pythonでデバイスメーカーを作成する その1(仕様検討編)



データの登録方法



データ登録用の画面を作成しても良かったのですが、150件近いデータを
手入力するのは面倒。

Google App Engineには、upload_dataという機能があるようです。
http://code.google.com/intl/ja/appengine/docs/python/tools/uploadingdata.html

デバッグ環境で試したのですが、一日調べても動いてくれませんでした・・・


Google App Engine(Python)でThriftを動作させる

Google App EngineでThriftを使う方法を調べてますので、
Thrift経由でデータを登録することにします。




データの形式



登録用のデータですが
1:番号(TAB)2:分類(TAB)3:名称
という形式のファイルを用意しました。


1    神器    アンカラ
2    神槌    シャルウル
3    神槌    ヤグルシ
...





Thriftファイル



thriftの定義体はこんな感じ。

■device.thrift

service DeviceUpdate {
    void add(1:i32 id, 2:string category, 3:string name),
    string get(1:i32 id)
}



データ登録用のメソッドaddと、ちゃんと登録できたかテストのため、
データを取得するためのメソッドgetを定義しました。


コマンドを実行して、定義体を得ます。


# thrift --gen py device.thrift






Google App Engineのモデル



データ登録用のモデルは、以下のように定義しました。


class Device(db.Model):
    category = db.StringProperty(required=True)
    name= db.StringProperty(required=True)






クライアントプログラム



クライアントのプログラムでは、データ登録用のテキストファイルを読み込み、
サーバーのDeviceUpdateを呼び出します。




サンプルソース



ソースはこんな感じ。

■サーバー側


# -*- coding:utf-8 -*-
import os
import logging

from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db

#Thriftを使用するため、importを追加
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.transport import TIOStreamTransport

#thriftコマンドで生成したファイルを追加
import sys
sys.path.append('./gen-py')

from device import DeviceUpdate
from device.ttypes import *

class DeviceModel(db.Model):
    category = db.StringProperty()
    name = db.StringProperty()

#Calculatorの実装
class DeviceUpdateHandler:
    def add(self, id, category, name):
        logging.info("add called!")
        logging.info(id)
        logging.info(unicode(category, "utf-8"))
        logging.info(name)
        
        device = DeviceModel(key_name=str(id), category=unicode(category, "utf-8"), name=unicode(name, "utf-8"))
        device.put()
        
        logging.info("add end!")

    def get(self, id):
        logging.info("get called!")
        device = DeviceModel.get_by_key_name(str(id))
        logging.info(device.name)
        logging.info("get end!")
        return device.name.encode('utf-8')

class MainPage(webapp.RequestHandler):
    def get(self):
        template_values = {}
        
        path = os.path.join(os.path.dirname(__file__), 'index.html')
        self.response.out.write(template.render(path, template_values))

    def post(self):
        
        self.response.headers['Content-Type'] = 'application/x-thrift'
        
        handler = DeviceUpdateHandler()
        processor = DeviceUpdate.Processor(handler)
        
        #自作したTIOStreamTransportをtransportとして指定する
        input_stream = self.request.environ['wsgi.input']
        output_stream = self.response.out
        transport = TIOStreamTransport.TIOStreamTransport(input_stream, output_stream)
        
        protocol = TBinaryProtocol.TBinaryProtocol(transport, True, True)
        transport.open()
        processor.process(protocol, protocol)
        transport.close()


#ログレベルの設定
logging.getLogger().setLevel(logging.DEBUG)

application = webapp.WSGIApplication([('/', MainPage)],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
    






■クライアント側


#!/usr/bin/env python
# -*- coding:utf-8 -*-

import sys
sys.path.append('./gen-py')

#
from device import DeviceUpdate
from device.ttypes import *

#お決まりのimport
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.transport import THttpClient

try:
    
    #アップロードしたgoogle app engineのURLを指定
    #transport = THttpClient.THttpClient("http://symfoware.appspot.com/")
    transport = THttpClient.THttpClient("http://localhost:8080/")
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    
    client = DeviceUpdate.Client(protocol)
    transport.open()
    
    
    f = open("data.txt", "r")
    for line in f:
        #タブ区切りのデータを取得
        ary_tmp = line.strip().split("\t")
        
        if len(ary_tmp) != 3:
            continue
        print "go!"
        #更新実行
        client.add(int(ary_tmp[0]), ary_tmp[1], ary_tmp[2])
        
    f.close()
    
    
    ret = client.get(1)
    print unicode(ret, "utf-8")
    
    #後始末
    transport.close()

#except Thrift.TException, tx:
except Exception, tx:
    print '%s' % (tx.message)





これで、デバッグサーバーへの登録はうまくいきました。
※google app engineへの登録はまだ試していません・・・





関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2010/03/13(土) 12:11:05|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Google App Engine Pythonでデバイスメーカーを作成する その3(アプリケーション作成編) | ホーム | Google App Engine Pythonでデバイスメーカーを作成する その1(仕様検討編)>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/345-153795d9
この記事にトラックバックする(FC2ブログユーザー)