最近のお仕事の話とか、ORM のはなしとか
たまに書いてますが、最近は、Teng使ったりしてます。ほかの ORM はあんま知らないです。つーか、ちゃんとした Web アプリとかあんまり書いたことないし、つまり、Web系の前線とかには全然居ない人です。地味に MES(製造実行システム)のバックエンドを作ってる人なのです。なので話半分くらいで見てもらえれば幸いです。
さてさて、そんな私ですが、
- 内製の WAF を使って、Web-API を書いてます
- WAF の機能は、ストアドを実行して XML を返す物体でした*1
- クライアントは簡単には変えれないので、XML のレスポンスは当面そのままでしょうねー*2
- ストアド書くのは楽しくないし、色々問題がでた(詳細はMySQL のストアドプロシージャの話を参照)ので、普通の SQL を叩けるように改造しました*3
- SQL 叩けるだけだと、簡単な SQL 書くのがだるいので、自分でテーブルデータゲートウェイを書きました
- 自分で書いたテーブルデータゲートウェイのメンテがだるいので、ありものを使おう、と思って、Teng を使えるようにしました(イマココ!)
と、言うわけで、最近は難しい機能の場合はめんどくさい SQL を手で書いて実行して、簡単なやつは ORM(Teng)に振るような感じで、過ごしていたわけです。
で、Teng に限らず、大抵の ORM はスキークラスを持っているのですが、僕はアホなので、テーブルの変更があったのにうっかりスキーマクラスを更新するのを忘れて、「ひでぶ」となることが多々あります。で、結構テーブルの変更は頻繁にあるので、「ひでぶ」も結構頻繁に起こります。テーブル数はアホみたいに多いので、スキーマクラスを動的に作成とかしたくありません。
いろいろ悩んだのですが、まあ解は2つかなー。
前にも書きましたが、スキーマの変更をテストしてるので、ORM のスキーマクラスもそのタイミングでテストしちゃえ、ってのが後者。で、基本的には前者でいきたいんだけど、Teng にその方向に手を入れるのは無理くさいし、自作するのはそれはそれで大変だなー、と思ってたりします。*4
つーか、そもそも何でスキーマクラスって必要なんだろ???と思ってちょっと考えてみたのですが、
- 重量級の ORM だと、そもそも DDL 管理もやってるから必要だよねー
- 軽量級(Teng とか DDL 管理やってないやつ)なら無くてもやってけるけど、そうすると Row オブジェクトが何にもできなくなっちゃうよねー
という感じかなー、と思います。例えば Teng だと、Row オブジェクトから UPDATE かけたりできるんですが、スキーマクラスが無いと主キーが分からないからできなくなっちゃいますよね。INSERT で Row オブジェクトを返すとかもできなくなっちゃう。あとは inflate/deflate もスキーマクラスがあった方がやりやすいかな。*5
上記のようなトレードオフやその他を検討した結果、
あたりが今やりたいことのようです。名前付きプレースホルダー以外は DBIx::Simple で機能的にはよさげなんですけどねー。
色々考えてみたわけですが、新旧 ORM は色々ありますが、歴史あるものは(僕が思いつきで作ったものと違って)それなりの理由とか思想があって良くできてるんだなー、と思った次第であります。
*1:だいぶ改造したけど、僕が書いたものではない
*2:これはこれで問題あるんだけど、今回の話とは関係ないので割愛
*3:SQL::Library というモジュールを使ってます。mod_perl じゃなかったら Data::Section::Simple を使いたかった。
*4:長期スパンで、自作の方向で検討してます。Teng とある程度互換性のあるブリッジが作れればいいかなー、と思ってます。
*5:inflate は Row オブジェクトで代替してもいいんじゃないかな、と思ってますが
*6:前述の Row オブジェクトから UPDATE はあればうれしいけど、INSERT で Row オブジェクトとか使ったことないや。どうやら欲しかったのはちゃんとしたテーブルデータゲートウェイだったようだ。最初にちゃんと作れば良かった...