戯れにO/Rマッパーを作ってみた。SQLite3決めウチのO/RマッパーならPythonを使えば100行ちょっとで書けてしまうんだよなあ。まあエラー処理とかまったく考えてないけどね。 このO/Rマッパーをちょっと書き換えたものが「みんなのPython Webアプリ編」に掲載されています。この書籍では,Webの基本からフレームワークを自作するところまで,Pythonを使ったWeb開発を一気通巻に解説しています。
さて。O/Rマッパーはこんな風に使う。
まずはクラスを定義してテーブルを作る。手抜きなのでカラム名とデータ型をタプルで並べて定義する。個々のデータを識別するため,テーブルには勝手にidというカラムを追加する。
>>> from simplemapper import BaseMapper >>> class TestORClass(BaseMapper): ... rows=(('num', 'int'), ('body', 'text')) ... >>> TestORClass.createtable()
INSERT = インスタンスを作る。
>>> for i in range(10): ... ins=TestORClass(num=i, body='body'+str(i)) ...
idを指定してインスタンスを生成すると,既存のデータをデータベースから取ってくる。ちみなに,UPDATEはアトリビュートを書き換えてからupdate()メソッドを呼ぶようになっている。
>>> ins=TestORClass(id=1) >>> ins <TestORClass:num=0, body=u'body0'> >>> ins.num=100 >>> ins.body=u'body100' >>> ins.update()
次はSELECTね。DjangoのO/Rマッパー風に,キーワードで条件を指定する。ちなみにSQLObjectとかSQLAlchemyとかでは,演算子のオーパーライドをしているので「boo==1」みたいに書くことができる。
>>> for ins in TestORClass.select(num_gt=5): ... print ins ... <TestORClass:num=100, body=u'body100'> <TestORClass:num=6, body=u'body6'> <TestORClass:num=7, body=u'body7'> <TestORClass:num=8, body=u'body8'> <TestORClass:num=9, body=u'body9'>
ソースは以下。結局やってることは文字列の切り貼りなんだけど,どこで何をやるのかってのが設計のミソなのかなあ。
あとパフォーマンスとかを考えるともっと別の実装があるはず。そこまで考えると100行ちょっとじゃ済まないですね。