#語りかける口調ですがあくまでも自分用のメモです。
へんてこなお任せJoinの仕掛けを、実は帰りがけに見つけておったのですが、なんとかソコまでこぎつけました。
あー定義?だいたい終えたよいちばん大きくて面倒なのは見て見ぬ振りしてるけど。
リレーション?なんか拍子抜けするくらい簡単にできたよ。構造が分かりはじめたらなんのことはないって風だったな。
このあたりは時間とってちゃんとまとめて、あたしみたいなphpを書くのがやっとみたいなパンプキンPGにもSQLAlchemy使える使い始めることくらいはできるようにしてやっからな。
もう$とか->とか書きたくなくなるわ。まあそれはいいや。

タイトルのlazyload と joinedload。説明はよく読まずに使ってみた。Lazyはテキトウなとかそんな意味だったと思うので、適当によろしくやってくれるのであろうと読み取りました心で。joinedloadはジョインしてロードしてくれるんだろうたぶん!!!!

(追記20130301)lazyつうのは遅延評価の事だったのね。必要なときに初めて仕事するよと。

実験に使ったのは、

  • BaseUser
  • NdiUser
  • Server
  • Nation

このよっつ。NDIで使うことを意図しているのでちょっと一般的じゃないですが、UserBasic,UserExtend,Blood,Jenderとかによみかえればいいよ!しるか!
NdiUserってのが、他のテーブルへのキー持ってるの。なんで、NdiUserからjoinしてあれこれ引っ張ってこれるわけだ。
で、session.queryにはそういういろんなオプションの書き方も用意されておるわけだ。
めんどくさい。めんどくさいんだよ……。
で、神パイソニスタさんたちが使う神ORMであらせられるところのSQLAlchemy(以下SA)には、リレーションの設定書いてあるならそれ読んでこっちで適当につないでやるわ、という仕掛けがあるみたいなのね。間違ってたらごめんでも結果はそうだ。

まずはこんな呼び出しをする。

    nu = meta.Session.query(NdiUser).filter_by(id=1).one()
    print nu
    print nu.baseuser
    print nu.server
    print nu.nation

こうすると、nu作るときにSQLクエリ一発、nu.baseuser呼び出す時にもう一発、nu.server呼び出す時にさらに一発投げるのだわ。つどつど、必要なときにSQL投げてんの。なるほどー

で、こんなん。

nu = meta.Session.query(NdiUser).filter_by(id=1).\
    options(lazyload(NdiUser.baseuser)).one()

lazyloadの後ろのカッコの中に、リレーションはってる部品をざらざら並べると、そのようによろしくやってくれるのね。

nu = meta.Session.query(NdiUser).filter_by(id=4).\
    options(lazyload(NdiUser.nation, NdiUser.server, NdiUser.baseuser)).one()

こんなん。lazyloadのとこをjoinedloadにすればまあ結果は同じだけど経緯が違うことがあるみたい。
結果はというと、指定したテーブルに関してはあらかじめクエリ飛ばすわけだから値を持ってる状態になると。
取り出すjoin先のテーブルが分かりきってる場合はそのほうがいいよね。

で、SQL文とかをechoさせながら動作見てたら、
joinedloadはテーブル一個だけつなぐ指定のときはSQL側でもjoinでつなげたクエリ発行してて、
つなぐテーブルが二個以上になるとjoinやめて個別にクエリ投げてるの。
lazyloadは連結したいテーブルの数に関わらず、joinはしないで個別に呼クエリ投げてるの。
なんでーなんでだー
あたしのやろうとしていることのレベル感でいくと、そんなもんはどっちでも結果同じなんだけど、気になるね。
というところまで今日は進んだのでした。
ネック解消したおかげで、ちょっと気分が軽い。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です