第17回:新春O/Rマッパー対決2009

株式会社ビープラウド

Django ORマッパー

多対多のリレーションを張るときに間のテーブルをORマッパー側で管理してくれる。

Queries

データ取ってくるときにjQueryっぽいメソッドチェーンが使える
〜.filter(〜).filter(〜).count()みたいな感じ。で、一つのSQLを生成して実行してくれる。

Saving

Modelのオブジェクトのsaveメソッドを呼び出しておしまい。
insert/updateを勝手に判定してくれる。

Admin

Modelから一般管理ページを生成する機能。

論理削除等の扱いがいい感じらしい

SQLAlchemy

Pythonの主要なORM
  • SQLObject
  • Django ORM
  • SQLAlchemy

SQLAlchemyのみData Mapperパターン、他2つはActive Recordパターン。

特徴
  • Data Mapperパターン・Active Recordパターンの両方が使える
  • 大規模向き
  • 同じような処理でも書き方がいくつかある
  • 学習コストは3つの中で一番高い
利用されてるアプリ
構成要素
  • ORM
  • SQL式言語
  • コネクションプーリング
  • スキーマ管理
  • Dialect(RDBMSごとに違う方言のサポート)
elixir
  • Active Recordパターンが使える
  • SQLAlchemyの拡張性の高さを生かして作られた。
Session
  • 一つのDB-Connection
  • Unit Of Workパターン
    • データベースに影響を与えるオブジェクトへの変更をすべて記録し、作業が終了した際にすべての変更を一度にデータベースに変更する。
  • Identity Map
    • DBから一度読み込まれたデータオブジェクトを保持し、再度参照した際に同じものを参照した場合は

selectする時もlistに詰める場合は遅延評価されるので、
Pythonコード中で何度queryを呼んでも、
実際に必要になるまでSQLが発行されない。
逆にeagerloadを使えば関連するものを事前に取っておける。

SQL式言語

メソッドチェーンでSQLを生成して実行できる。
Pythonでは演算子オーバーロードができるので、
.where(user_table.c.id < 10000)の括弧の中は、
booleanではなく条件を表すオブジェクト、という風にできる。

ほとんどのORMはレコード追加時のデフォルト値の設定をアプリ側でしかできない。
SQLAlchemyも普通はアプリ側でやるが、DBサーバ側でやらせるような定義もできる。

関連テーブルは自分で定義しないといけない(Djangoとの違い)

質疑応答
  • Data Mapperのいいところは何か?
    • DBのスキーマが複雑すぎる場合はEntityを定義するのが大変
    • 既存のDBがある場合は
  • 1Modelで複数tableとかもできるらしい

LINQ to ○○○

LINQの仕組み
  • コンパイル時にクエリ式をメソッドチェーンに変換する
LINQを支える仕組み
  • パイプラインパターン
  • 拡張メソッド
    • 既存クラスにメソッドを追加出来る。
    • 拡張メソッドをusingしたcsファイルの範囲内で、該当クラスにメソッドが追加される。
    • コンパイル時にただのstaticメソッド呼び出しに変換されている。
  • ラムダ式
    • 式ツリーを扱える
LINQ to ○○○
  • LINQ to Object
    • IEnumerableなコレクションからデータを取り出したりする
  • LINQ to XML
    • XMLのツリーを簡単に扱えるオブジェクトモデルを用意し、それをLINQで扱う。
    • XElement
  • LINQ to SQL
    • 軽量ORマッパー
    • 構造的には様々なRDBMSをサポートできるのだが、実際にはSQLServer2005/2008のみサポート
    • サポートが中止される
    • many to manyマッピングが未サポート
    • Entityのクラスやプロパティに属性をつける事でマッピングを定義したりする。
  • LINQ to ENtities
    • ADO.NETのサブフレームワーク
    • RDBMSを抽象化するレイヤとオブジェクトをちゅうしょうかするレイヤからなる。
    • ORマッパーとしてみたときには重量級
    • いっぱい設定ファイルを用意しないといけない
  • LINQ to DataSet
    • 表情のデータをキャッシュするストレージに対してLINQクエリを使う
    • Memcachedみたいの
LINQ to ○○○を作る
  • 独自のデータソースを使う
    • LINQの操作に対応するメソッドを全部書く
  • IQueryableを使う