DBIx::Classを使ってみた

いまいち、Class::DBIとDBIx::Classの違いがわかっていないのだけど、Catalystで作りたいものがあったので Perl/DBICなどみながら、いろいろさわってみてる。

My Kwiki: HomePage

Class::DBI inspired ORM designed to be resultset-oriented rather than table-oriented - so native support for views, aggregates (GROUP BY etc.), better automatic JOIN-ing and the ::Sweet search features done properly.

Class::DBIがテーブル指向なのに対して、DBIx::Classはresultset指向らしい。確かにCDBIだとページの処理用にプラグインがあったりするけどDBIx::Classだとさくさく書けた。

もうちょいドキュメント 読む必要があるけど、なかなか楽しげ。

ちなみに、下の二つは同じらしい。今日書いててちょっと悩んだのでメモ

$c->model('DBIC')->resultset('Items')

2006.10.17追記

DBIx::Class::Manual::Glossary - Clarification of terms used. - search.cpan.org

ResultSet

This is an object representing a set of data. It can either be an entire table, or the results of a query. The actual data is not held in the ResultSet, it is only a description of how to fetch the data.

ResultSetとはデータセットを表すオブジェクトで、テーブル全体であったり、クエリの結果だったりする。

Catalyst::Plugin::Flavourはdev向けでいれる

catlxom動かんから週末ちゃんとみようとか思ってたら、ナイスなタイミングでエントリが。

mizzy.org

まず、cpan コマンドで Catalyst::Plugin::Flavour をインストールすると、バージョン 0.02 が入るのですが、これだと catlxom は動きません。DEVELOPER RELEASE の 0.029_01 のソースをもってきてインストールする必要があります。

これで解決。

で、家のサーバーで動かそうとFC1(perl-5.8.3)な環境で試したら、

$ ./script/catlxom_server.pl 
Operation `""': no method found, argument in overloaded package
 Catlxom::Plugins at /usr/lib/perl5/5.8.3/overload.pm line 97.
Compilation failed in require at ./script/catlxom_server.pl 
line 49.

perlのバージョンあげなあかんかな。

WindowsでCatalystとPlaggerを動かす

学会のwirelesslanがcolinuxで使っているプライベートアドレスとぶつかっていて、外につなげながら、colinuxでコードを書くことができん。アドレス変えるのも面倒なので、WindowsでCatalystとPlaggerを動かすことにした。

上のサイトを参考にしたヨ。

あと、ChangeLog パーザもみつけたので、コレをいじってプラグインを書けば、clmemoをplaggerに読ませて、gmailにメモ送りができるかな。

catlxom

なんか最近サーバー不調だし、新しいマシン買ってmod_blosxomにでも乗り換えようかなとか思ってたら、catlxomなるものの開発が進んでるらしい。

をを~素晴らしい

早速svn co してcolinux上で走らせてみますよ。

$ ./script/catlxom_server.pl 
You can connect to your server at http://colinux:3000
[Wed May 24 22:04:17 2006] [catalyst] [error] 
Caught exception in Catlxom->default "Can't locate object 
method "year" via package "html" (perhaps you forgot to load "html"?) 
at /home/kzfm/catalyst/catlxom/plugins/Filter/Date.pm line 15."

とエラー。Date.pmみてみると

    for (qw/year month day/) {
        if ( $c->flavour->$_ ) {

だから、Catalyst::Plugin::Flavourのここらへんから追っかけていけばいいのかなぁ。

$c->flavour( $c->config->{flavour}->{default_flavour} || 'html' )
        unless $c->flavour;
    $c;
}

でも、なんでこれが、htmlロードすんの忘れてんじゃない?というエラーになるのかが良くわかってない。$c->flavour->$_が気になる。週末にちゃんと読もう。

あと、IRCくらい扱えるようにしといたほうが色々といいのかなとか思ってChatZilla入れたけど、いまいち使い方がわからん。これも週末に少し触ってみよう。

Catalyst::Example::InstantCRUD

CatalystのML見てたらDBICベースのCRUDフレームワークもあるそうな。

  • Enzyme
  • CDBIベース
  • modelやcontrollerのヘルパースクリプトで指定
  • Catalyst::Example::InstantCRUD
  • DBICベース
  • HTML::Widgetもつかっとるよ
  • catalyst.plの代わりにinstantcrud.pl

というわけで、手持ちのmysqlのデータベースでやってみた。

$ instantcrud.pl -name=Kz::Sample -dsn='dbi:mysql:kzsample' -user=kzfm
-password='test'

こんだけ。

あとはサーバー起動するだけで超ラク!

でも、遺伝子発現DBでやってみたら、

$ instantcrud.pl -name=My::Exp -dsn='dbi:SQLite:myexp.db'

Caught exception in My::Exp::Controller::Expressions->list 
"DBIx::Class::ResultSet::search(): no sth generated via sql: 
SELECT me.id, me.affyid, me.d0, me.d2, me.d4, me.d10 FROM 
expressions me LIMIT 10 at 
/usr/lib/perl5/site_perl/5.8.3/Catalyst/Example/Controller/InstantCRUD.pm line 220"

とエラー。そもそもDBICちゃんとわかってないので、これ以上はちょっとな、、、ってことでヤメ。

Catalystにも幾つかCRUDフレームワークがあることがわかったのでよしとしよう。

CatalystとGD::Graph::linesで作った遺伝子発現データベース

Ruby on Railsで、遺伝子発現データベースを!というエントリがすんげー面白かったので、ここはひとつperlなcatalystでやってみたヨ。

ichan::Weblog - Ruby on Rails Gruffを使って、11分で作る遺伝子発現データベース

ごく簡単な遺伝子発現データベースをRuby on Rails で作ってみました。時系列の遺伝子発現データを取りこんで、Gruffで折れ線グラフで表示します。bioinformaticsやマイクロアレイ解析と関係がないかたもGruffの使用例として参考になると思います。

一応、10分でできるRoRなやつをトレースしたことがある。なんで、今回ムービーも見ながら、できるだけ同じような感じで構築してみた。ちょっとCatalystとRoRの対比をしておきますと、

RoRはレールにのっかってスイスイッと。特にDBまわりとの連携がすごく楽。対してCatalystはページングの処理とかプラグイン使わないといけないし、フォームの用意も自前でやらないとあかん。 画像吐き出しはRoRはコントローラで処理しているが、CatalystはViewに押し込んでいる。GD使うつもりだったけどTTでGD呼ぶのは抵抗があったので、Catalystのプラグイン探したけどなかった。そんなわけで結局、画像処理はTTのGD::Graphプラグインで行なってます。

個人的な見解だけど、RoRは定型的な処理は楽ちんっぽいです。CatalystだとページングにClass::DBI::Sweet使うかClass::DBI::Pager使うか悩んだり、Class::DBI::Sweetのヘルパーないかと探し回ったりと、コードの長さの割りに時間がかかってしまった。でも、viewに画像処理押し込むとコントローラーいじらなくてすむのでそれはそれでいいのかな?

さて手動かし履歴(かなり端折ってますが)

まず、発現データの処理とDB化は元ネタサイトどおりにbioconductorで。スクリプト動かしたら、パッケージ足りなかったので

source("http://www.bioconductor.org/biocLite.R") biocLite(c("mgu74av2cdf"))

を。あと、Rでapllyを使うと早いのね、勉強になった。今度他のデータで試してみよう。

$ catalyst.pl Expview
$ cd Expview
$ ./script/expview_create.pl view TT TT
$ script/expview_create.pl model CDBI CDBI dbi:SQLite:myexp 

これだと、ページングの処理が出来ないので、lib/Expview/Model/CDBI.pmに

use Class::DBI::Pager;

を追加。

そしてコントローラーまわりをいじる。lib/Expview/Cotroller/Root.pmを編集


sub list : Global {
    my ( $self, $c ) = @_;
    my $page = $c->request->param('page') || 1;
    my $pager = Expview::Model::CDBI::Expressions->pager(10,$page);
    $c->stash->{items}  = $pager->retrieve_all;
    $c->stash->{prev_page}  = $page-1;
    $c->stash->{next_page}  = $page+1;

$c->stash->{template} = "templates/view.tt";
    $c->forward('Expview::View::TT');
}

sub graph : Global {
    my ( $self, $c ) = @_;
    my $id = $c->request->param('id');
    my $exp = Expview::Model::CDBI::Expressions->retrieve($id);
    my @expression = ($exp->d0,$exp->d2,$exp->d4,$exp->d10);
    $c->stash->{exp} = \@expression;
    $c->stash->{affyid} = $exp->affyid;

$c->stash->{template} = "templates/graph.tt";
    $c->forward('Expview::View::TT');
}

こんな感じで、リスト用のルーチンと画像表示用のルーチンを記述。TT用のテンプレートもroot/templatesに用意します。

これでOK

リストはこんな感じで表示されますが、Catalystは自前でテンプレート書かないといけないのに対して、RoRはそこも面倒見てくれている。この部分のコストはお気軽さに結構きいてくるかも。

expview

画像もGD::Graphで。ちょっと見栄えがよくないが、でもテンプレートいじれば綺麗になるヨ。

expgraph

今回作った、expview.tar.gzをダウンロードできるようにしておきました。

$ tar xvfz expview.tar.gz
$ cd Expview
$ ./script/expview_server.pl

でport3000番にアクセスすればいいはず。

5/15追記

Catalyst::EnzymeというCatalyst用CRUDフレームワークを使えば、テンプレートとかCRUDまわりをまとめてやってくれるので、10分くらいでできそうな感じデス。

Catalyst::View::GraphVizを使ってみた

Catalystの画像描画モジュールを探し回ってたときに見つけて面白そうだと思っていた、Catalyst::View::GraphVizを使ってみた

まずはインストール。GraphVizのサイトにRPMがあったのでそれを利用した。perlモジュールはcpanから。ちなみにGraphVizモジュールの作者はYAPCで公演してた

$ rpm -Uvh /home/kzfm/graphviz-2.8-1.fc1.i386.rpm 
$ rpm -Uvh /home/kzfm/graphviz-devel-2.8-1.fc1.i386.rpm 
$ cpan -i GraphViz
$ cpna -i Catalyst::View::GraphViz

さて、ここからcatalyst

$ catalyst.pl Gview
$ cd Gview
$  ./script/gview_create.pl view GraphViz GraphViz

ってやって、Root.pmをいじるが、とりあえずデフォルトで出力させてみた。

sub default : Private {
    my ( $self, $c ) = @_;
    my $g = GraphViz->new();

$g->add_node('kzfm');
    $g->add_node('yuki', label => 'NewComer\nyuki');
    $g->add_node('hana', label => 'hana\nDog');

$g->add_edge('kzfm' => 'yuki');
    $g->add_edge('kzfm' => 'hana', label => 'pet');
    $g->add_edge('yuki' => 'kzfm');
    $c->stash->{graphviz}->{graph} = $g;

if(!$c->res->body) {
        if($c->stash->{template}) {
            $c->forward('Gview::View::TT');
        } elsif($c->stash->{graphviz}->{graph}) {
            $c->forward('Gview::View::GraphViz');
        } else {
            die("No output method!\n");
        }
    }
}

GraphViz

タグの関係を視覚化したり、スキーマ書いたり色々使えそう。論文とか化合物の類似性の視覚化とかでもいいいかも。階層クラスタリングが見にくい場面とかでこういった方法取れるかな。

Catalyst使わないでblosxomのタギングプラグインに組み込むというのもありかな。image mapでだせるのでおもろいかも。

Ajax使ってる例もあったので、Catalyst+Prototype.jsでやるのも面白いかと思ったり。

Catalyst::Enzymeでかなり楽ができる

CatalystとGD::Graph::linesで作った遺伝子発現データベースでCRUDメンドイとかいたたがCatalyst::EnzymeというCatalyst用CRUDフレームワークがあったので使ってみた。

CatalystにEnzymeなんて、バイオインフォ+ケモインフォな僕にはソソル名前のフレームワークだヨ。

$ catalyst.pl Eview
$ cd Eview/
$ ./script/eview_create.pl view TT Enzyme::TT
$ ./script/eview_create.pl model MyExp Enzyme::CDBI dbi:SQLite:dbname=db/myexp.db 
$ ./script/eview_create.pl controller Expressions Enzyme::CRUD MyExp::Expressions

とかやって、テストサーバー立ち上げるとこんな感じで。

Expview

かなり、楽チンだ。

Catalyst::Enzyme - Catalyst用CRUDフレームワーク

前提条件

アプリケーションがClass::DBIベースのモデル・クラスを使っていること。

アプリケーションの一部として(たぶん内部用の管理インタフェースとして)、あるいは単に何かのとっかかりとしてCRUD機能を使いたいと思っていること。

(コードにしろテンプレートにしろ)修正するためにソースを読んで理解しようとする気構えがあること。Enzymeを使えばいままでより速く、また少ないコード量で始めることはできますが、その後、自分自身の用途にあわせたフレームワークへと作り込んでいく必要はあるのです。自分の必要に応じてどんどん変更していってください。

特に最後に書いてあるように、ソース読めないと作りこみではまるかもしれん。

YAPC行ってきたヨ (2)

楽だ

XSの話とCatalyst関連の話題が面白かった。XSのサンプルは後でいじってみる。科学技術計算系のゴリゴリやるやつはやっぱCとか書けるようにしといたほうが幅が出ていいのかナァなんて思っているのでこれをきっかけに少し頑張ってみるかな。

Catalystは最近プラグインつくってみたかったりするので今日の話はなるほどなところが多くて参考になった。

Larry WallのKeynoteは面白かったが、深すぎてついていけないところが多々あった。

CDBIでCOUNTするには

まぁ、いまのところ(というか二日目なので)出来るだけset_sqlを使わないゾ週間は守られていますヨ。

いまdel.icio.us.li.keを作っているのだが、あるURLを何人がブックマークしているかカウントする必要が生じた。

CDBIってcountメソッドサポートしてなさげ、ピンチ!

でも大丈夫、しのいだ。Class::DBIのPluginClass::DBI::Plugin::AbstractCountってのがあったからな。

catalystのModelに

use Class::DBI::Plugin::AbstractCount;

といれたら、あとは

$c->stash->{itemlist}->[$i]->{sub_users} = Publicious::Model::CDBI::Items->count_search_where( { pubmedid => $col->pubmedid});

という感じで、カウントできる。