BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース DataMapper、バージョン1.0へ到達

DataMapper、バージョン1.0へ到達

原文(投稿日:2010/07/21)へのリンク

DataMapperはRuby向けのオブジェクトリレーショナルマッパーであり、最近マイルストンが1.0へとたどり着いた。このリリースはRailsConf 2010の間にDirkjan Bussink氏プレゼンテーションで発表された。

DataMapper(DM)はこの2年間、コミュニティプロジェクトによって育てられてきた。DMは高速でスレッドレーフで多機能なORMだ。InfoQは主要な開発者であるDan Kubb氏と話す機会を得た。

DataMapperはバージョン1.0がリリースされたが、これは前バージョンの0.10からの大きなそして重要なバージョンアップだ。氏はこのマイルストンの内実を教えてくれた。

1.0へバージョンアップするかどうか決めるのはちょっと難しかったです。1.0は完璧ですべての課題を解決していてほしいという考えがある一方で、完璧に完成しているソフトウエアなど存在しないこともよくわかっていました。また、決断を下すためのほかの条件もあります。私たちの場合、1.0が意味することを次のように決めました。すなわち、APIが安定した状態にあること、つまり、皆が使っているパブリックAPIとプラグインの開発者が使う"セミパブリック"APIに変更の予定がない状態です。ほかにもいろいろあるかもしれませんが、2.0がリリースされるまでのマイナーバージョンアップでは1.0のAPIは問題なく動作することが重要点です。DMが生まれたとき(たった2年前ですが)、APIは常に変更が行われていましたが、この6ヶ月から12ヶ月の間で落ち着きました。今のAPIの動作の仕方にはとても満足しています。

実際はDataMapper 1.0は他のRubyのオープンソースプロジェクトがバージョン2.0または3.0になった状態と同じ位置にいます。DMの背後にはとても活発なコミュニティがあり、DMに関連する150ものgemとこれらのgemに関わる1000人を超える開発者がいます。また、DMが様々なデータ永続化ストレージエンジンで使えるように40ものアダプタがあります。普通のRDBMS用のアダプタもありますし、NoSQLシステム向けのアダプタやSalesforceのようなウェブサービス用のアダプタもあります。

DataMapperの設計は、ストレージの関心事とプログラムが利用するフロントエンドのAPIを疎結合にしておけます。オブジェクトの照合用に基本的な述語を用意していますが、アダプタの作者はこれとは別に自由にすべてを実装してもいいですし、部分的に実装してストレージエンジンを扱うことも可能です。公式のDMのプラグインのほとんどは、特定のストレージエンジン向けの特別な実装をしていませんが、どんなアダプタを使っても問題なく動作するはずです。

DataMapperはActiveRecordのような他のORMとは異なる実装方式を採用している。ActiveRecordはRailsでデフォルトで利用できるORMだ。Ruby開発者が魅力を感じる特徴はどんなところか尋ねたところ、氏は次のように説明した。

開発者が魅力を感じる特徴はたくさんあると思いますが、まず説明したいのは、ActiveRecordしか使ったことがない開発者のほとんどがすぐに気付くのは、DMが本質的に宣言型であるということです。DMのすべての属性や関連はモデル内に宣言されます。この宣言はデータベースよりも優先される定義です。制約や振る舞いをひとつの場所に記述することでモデルの定義がすべてに反映されます。そしてこの定義がマイグレーションやバリデーションなどに利用されます。例えば下記の単純な例を見てください。

 class Contact
   include DataMapper::Resource
   property :id,   Serial
   property :name, String, :length => 1..30, :required => true, :unique => true
 end

RDBMSを利用するという前提で話をします。DataMapper.auto_migrate!を呼ぶと、ふたつの列を持つ"contacts"という名のテーブルが作成されます。"id"列は主キーになり連番が振られます。"name"列はCHAR(30)でNOT NULLでユニークインデックスが張られます。加えて、バリデーションが埋め込まれます。すなわち、idとnameの値が存在し、idがInteger型でnameがString型であり、nameの長さが1文字から30文字以内に納まり、nameがnilでなく、nameがユニークであることを検証します。

ActiveRecordを使った場合、複数のファイルを移動しながら作業しなければなりません。しかも、DBと開発しているバリデーションが一貫しているように注意しながら作業する必要があります。開発者は多くの場合、このようなことすべてに悩まされないようにバリデーションだけを定義して、DBは"ダンプ"データの保存場所として扱います。DMを使えばこの作業がかなり楽になります。DMは基礎になっているデータストアの強みを利用し、データストアをダンプの保存場所として扱わなくてもすむ方法を使うように促します。

DMがまだ無いころ、ARを使って開発しているときに、私はいつもDBにどんなフィールドがあるのかいつも忘れていました。なので、annotate_modelsのようなプラグインを使ってモデルの最上部に現在のDBスキーマの情報をコメントとして書いておきました。実際、この作業はDMが宣言的に行ってくれることと完全に重複しています。なんの利益もなしにこんなことをやっていたわけです.. また、バリデーションや初期のマイグレーションも定義しなければなりませんでした。

Ruby on Rails 2.xの人気と完全に書き直されるRails 3の登場が近づく中、DMとRailsを統合するプロジェクトが生まれている。“通常”の方法をやめようと考えている開発者は誰でも、ActiveRecordからDMへ変更することで獲得しうる利益とそれがどれだけ簡単な実装なのかについて対比して考える必要がある。DMをRailsで使うことについて氏と議論したところ、とても活発な開発努力がされていることがわかった。

DMをRails 2 と 3で利用できるようにするために相当な数の開発者が作業をしてます。この作業は順調に進んでいます。Rails 2.xのgemはrails_datamapperという名前で、Rails 3用のgemはdm-railsという名前です。単一のgemで両方のバージョンをサポートするよりも、バージョンごとにプラグインを分ける方式にしました。これは、高速に開発されているRails 3と間違いなく同期をとるためです。数人のDMの開発者がRails 3の最新の開発状況を追跡し、最新のRails 3でもdm-railsが完璧に動作するようにしています。

私たちの現在の一番の関心事はDM 1.0がActiveRecordと同じようにRails 3で利用できるようにすることです。Railsの中心的な開発者たちはRails 3をORMにとらわれないものにするために長い道のりを歩いてきました。そして、DataMapperの開発者たちがDataMapperのすべての機能が適切に動作するために必要なフックを確保できるようにするために、Railsの中心的な開発者たちはDataMapperの中心的な開発者と協力しました。過去Rails 2のときには、DMを統合するために様々なハックが必要でしたが、今回はそれは必要ありません。

dm-railsが次第に出来上がりつつあるのはとてもうれしいことです。将来にはdm-railsの"ガッツ"が抽出されて、gemになってすべてのウェブフレームワークで使えるようになり、一貫したrakeタスクやモデルの(リ)ロードなどを提供するでしょう。こうなればのりのようなプログラムを使うことで、DMが他のウェブフレームワークで利用できるようになり、フレームワークの更なる簡素化が実現できます。

ActiveRecordの代わりにDMを使うという考えからは次のような疑問が湧く。すなわち、ほかのORMを使う場合の約束事に開発者はどのくらい簡単に適応できるのか。単にRailsを賞賛しているだけでなく、DMはRailsプロジェクトのActiveRecordを完全に置き換えるのか。私たちはこの点をはっきりさせたかった。

ええ、そのとおりです。DMを使う場合、既存のクラスをモジュールに含むことができます。ARのほとんどのファインダと同じファインダがDMにあります。ARよりもシンプルなファインダもあります。また、バリデーションもARと全く同じです。DMに関係するgemは150もありますので、例えば、構文が違っている場合があったとしても、プラグインを使っても使わなくても、DMはそのままでARと同じように動作すると思います。

すべての属性や関連がモデル内で宣言できるのはDMの優れた特徴だが、これはRailsのマイグレーションがもはや不必要であることを暗に示しめしているようにも考えられる。しかし、氏はマイグレーションがこれからも必要であるということをすぐに示した。

部分的には正解です。マイグレーションは開発中にはまだ必要です。データベースに変更を通知しなければならないからです。それも今までの情報を保持する方法で通知しなければなりません。一方でauto-migrationsはすべてのデータベースをドロップし、モデルの新しい宣言に合致するテーブルを再作成するので破壊的な変更になります。auto-upgradingは新しいテーブルや列、インデックスを追加しますが、列名の変更や列の削除、列の分割などにauto-upgradingを使うのはスマートなやり方ではありません。マイグレーションで何がしたいのか明示的に指定することなしにこのような作業がスマートにすることが可能であると確信を持って言い切ることはできませんが、追加系の変更をするときにはauto-upgradingをマイグレーションのひとつの方法として使い、複雑な変更や破壊的な変更をするときは明示的なマイグレーションをするという方法を採用すれば、マイグレーション作業自体が簡単になると思います。

また、もっと作業が簡単になるような、マイグレーションを*generate*する方法も考えています。モデルとデータベースの差分をとって、それをもとに変更を実行するマイグレーションを生成することは可能なはずです。開発者はマイグレーションを見て、意図した通りになっているか確認してからデプロイをしなければならないでしょうが、手動でマイグレーションを書くのは必要のない作業だと思います。なので、追加系の変更、破壊的な変更、複雑な変更を最小限の労力でわかりやすくできるようにしたいと思っています。

DMはオートマイグレーションという概念を導入している。これを使えばRailsの典型的なマイグレーションよりも利点を得られる。

高速な開発をしている場合、この機能はとても便利です。TDDで開発する場合、モデルをスペックの間を素早く移動しながら新しい属性を追加するほうが、モデルやマイグレーションやスペックの間を行き来して、DBにテーブルの変更を反映するためにいちいち作業を中断してマイグレーションを実行するよりもはるかに簡単だからです。

このプロジェクトの最も魅力的な点のひとつは、DMへ機能を追加できるプラグインがたくさんあることだ。CouchDBやRESTスタイルのストレージのような様々なストレージへアクセスできるプラグインがある。Google AppEngineへアクセスできるプラグインもあるのだ。このGoogle AppEngineのデータストレージにアクセスする機能は特に興味深い。Googleのインフラ上のJRubyで動作するアプリケーションを作っている開発者もDMを利用できるからだ。この点について氏に尋ねたところ、

dm-appengine-adapterについては私はそれほど関わっていませんので、詳細な点については教えられません。ただ、私はいくつかのカンファレンスでGoogleのApp Engineプロジェクトで働いているJohn Woodell氏と話したことがあります。このアダプタについての話もしましたし、DMのアダプタAPIの開発に影響を与えた氏のチャレンジについても話しました。

聞いている限りではこの開発も順調なようで、DMのほとんどの問い合わせシステムをサポートしています。Googleからすれば、自分たちのApp Engine向けのオブジェクトマッパープロジェクトを取り込んでしまった形になります。このプロジェクトはBumbleと呼ばれていましたが、私が知る限り牽引役がいませんでした。他方、DMには大きな開発コミュニティがあり、多くのプラグインがあります。唯一の課題は最初のアダプタを作ることですが、私が聞いた限りでは非常に難しい作業というわけではないそうです。私も少しの間、特定のストレージエンジン向けのアダプタを作っていたことがありますが、そのときはオブジェクトマッパーを完全に最初から作りました。

私が気付いたのは、この点は誰も指摘していないDMの利点のひとつだということです。各ストレージエンジンへの対応がDMに実装されるごとに、中心的な開発チームへフィードバックされます。このフィードバックは最終的には次回のアダプタAPIのリリースで反映されます。したがって、作成された各アダプタは、他のアダプタを高機能にし、追加しやすくする役目を果たしているのです。例えば、MongoDBのアダプタは現在開発中ですが、このアダプタにはDMがまだサポートしていない概念があります。しかし将来、DMはこの概念の影響を受けるでしょう。このアダプタの作者が、DMをアップデートしてこの未実装の概念をサポートするのを手伝ってくれるからです。MongoのEmbedded ResourcesもEmbedded Valueと呼ばれるようなものを使って実装することができます。既存のアダプタとともに利用しても問題なく動くでしょう。

DataMapperはRails開発者に使われることを想定して作られたわけではない。私たちが聞きたかったのはDMはどんなタイプの開発者を対象にしているのか、ということだ。

DMが対象としている開発者は、これからのほとんどのアプリケーションが構造化されたデータ向けのリレーショナルデータベースと非構造化/変数データ向けのNoSQLの組み合わせでできるということに気付いている開発者です。また、RDBMSが不向きな場合もあるということがわかっている開発者です。RDBMS vs. NoSQLという議論は愚かな議論です。ユースケースによって一方が他方より優れている場合があるだけです。ほとんどの一般的なアプリケーションでは両方の組み合わせです。どちらか一方が優れているということはありません。

DataMapperについての更なる情報はプロジェクトのウェブサイトで確認できる。入門のチュートリアルもある。

この記事に星をつける

おすすめ度
スタイル

BT