SQLObjectすばらしいシリーズの続きね。
たとえば,model.pyに以下のようなクラスを定義するとする。MultipleJoinを使って一対多のリレーションを表現。リレーション先では,ForeignKeyを使う。
from sqlobject import * from turbogears.database import PackageHub hub = PackageHub("intest") __connection__ = hub class Container(SQLObject): """ コンテナクラス(フォルダみたいなもの) """ sub = MultipleJoin("Sub") class Sub(SQLObject): """ コンテナの内容物 """ container = ForeignKey("Container")
「tg-admin sql create」して「tg-admin shell」でシェルに入る。
In [3]:c = Container() # コンテナを作る In [4]:s1 = Sub(containerID = c.id) # 内容物を作る,このとき,外部キーを指定してコンテナに入れる In [5]:s2 = Sub(containerID = c.id) # もう一つ作る In [6]:c2 = Container() # ダミーのコンテナを作る。 In [7]:s3 = Sub(containerID = c2.id) # ダミーのコンテナにダミーの内容物を入れる In [8]:c.sub # リレーション(リスト)を確認 Out[8]:[<Sub 1 containerID=2>, <Sub 2 containerID=2>] In [9]:s2 in c.sub # 比較演算子でリレーションを検査 Out[9]:True In [10]:s3 in c.sub # s3はcの中にはないのでFalse(偽)が帰ってくる Out[10]:False
というように,リレーションも簡単に表現できてしまうのですね。しかも,inみたいなPythonicな演算子を使ってリレーションされている要素を検査をすることができる。「できる限りPythonicにRDBMSを扱おう」というのがSQLObjectの思想。
dev.cfgのdburiに"?debug"というようにパラメータをくっつけ,発行されているSQLを表示すると分かるけど,リレーションされたデータが選択されるのは,リスト(この場合はc.sub)にアクセスしたとき。つまり,実際に利用しない限りは選択されないのね。
ちみなに,SQLObjectを作っているIan Bickingと言う人とはPyCon 2006のTurboGears Sprintでちょっとお話ししたことがある。常に最悪のケースを考えながらコーディングする,という気質の,良い意味で気の回る技術者。そういう人の作っているO/Rマッパーなので,私はSQLObjectを信頼しているし,かつ好きでもあるのです。SQLObjectのソースをみると,Python的なハックが沢山あってとても楽しいですよ。
ちなみに,最近書いたTurboGearsのmookの原稿は,SQLObjectのクイックリファレンスとしても利用できるようになっています。ぜひお手元に一冊:-)。
まあそんな感じで。