Amazon SimpleDBをPythonからちゃんと使う
なんかいつの間にかbotoが1.9bになっていてGentooのパッケージにもしっかり格納されている。そして1.9bではquery()メソッドは消されており、2007年時点での説明書は全く役にたたない。amazonaws.comというサイトには、API一覧っぽいのが掲載されているが、やはり説明されている部分は限られている。
こういう時はソースを読むんですよ。
ということでboto.sdb.db.modelあたりを読んでみた。こういうことらしい。
(1) SimpleDBに格納したいクラスはboto.sdb.db.Modelを継承させる。使える型はboto.sdb.db.property.*に定義されている。
from boto.sdb.db import Model from boto.sdb.db.property import * ... class TestDB(Model): f_name = StringProperty() l_name = StringProperty()
(2) そのクラスを格納するDB(RDBでいうとテーブルに相当)を/etc/boto.cfgに記述。実体はSimpleDBでいうDomain。
[DB_TestDB] db_name = testdb
(3) 当然、そのドメインはなんらかの形で作っておく必要がある。
import boto conn = boto.connect_sdb() domain = conn.create_domain("testdb")
簡単なコードを書いてみた。
#! /usr/bin/env python import boto from boto.sdb.db.model import Model from boto.sdb.db.property import * from datetime import datetime import time class TestDB(Model): f_name = StringProperty() l_name = StringProperty() registered_datetime = DateTimeProperty() def main(): conn = boto.connect_sdb() conn.create_domain('testdb') t = TestDB() t.f_name = "Masayang" t.l_name = "Nakamura" t.registered_datetime = datetime.now() t.put() #これで書き込める decay = 0 decay_max = 10 success = False while success == False: result = TestDB.get_by_id(t.id) if result: # Eventually Consistentなので直後は読めないことがある print result.f_name print result.l_name print result.registered_datetime success = True else: #読めなかった場合は読めるまでリトライする if decay < decay_max: decay += 1 time.sleep(decay) else: #ダメなら諦める success = True # 正しくは例外を上げるべきなんだろうけど... if __name__ == "__main__": main()
このやり方なら、各種Webフレームワークのバックエンドとしても使えそうだ。boto.sdb.db.modelを読む限りReferenceも使えるようなので、関連しあったクラスの格納にも使えることであろう。
おまけ
SimpleDBにはこんな感じで格納されている。
>>> import boto >>> conn = boto.connect_sdb() >>> dom = conn.get_domain('testdb') >>> rs = dom.select("SELECT * FROM testdb") >>> rs = dom.select("SELECT * FROM testdb") >>> for r in rs: ... print r.name ... print r ... ab1a342a-b8c4-439c-b0dd-010062d194f2 {u'__module__': u'__main__', u'__lineage__': u'object.Model.TestDB', u'l_name': u'Nakamura', u'f_name': u'Masayang', u'registered_datetime': u'2010-08-02T13:07:05Z', u'__type__': u'TestDB'}
→SimpleDBは各要素をUTF8文字列で格納する。botoがPythonの型と文字列との変換を引き受けてくれる。各レコードのキー(simpleDBでいうname)はbotoが勝手につけてくれてるね。便利。