このサイトについて

TurboGearsが使ってるO/R MapperであるところのSQLObjectのMultipleJoinは凄いよこりゃ

TurboGearsが使ってるO/R MapperであるところのSQLObjectのMultipleJoinは凄いよこりゃ

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のクイックリファレンスとしても利用できるようになっています。ぜひお手元に一冊:-)。

まあそんな感じで。

2010-08-27 04:40