07032007 dbic
こんなテーブルで
あるタグと一緒に現れるタグの集計をとりたくて、selfjoinをしたかったのでDBIx::Class::ResultSetを参考に書いてみた。
alias指定して、左から右へ配列のリファレンスでつなげていくイメージでよいのかな。join_typeも指定するのを忘れない。
ちょっと探すのに手間取ったのでメモっておく。
07032007 dbic
こんなテーブルで
あるタグと一緒に現れるタグの集計をとりたくて、selfjoinをしたかったのでDBIx::Class::ResultSetを参考に書いてみた。
alias指定して、左から右へ配列のリファレンスでつなげていくイメージでよいのかな。join_typeも指定するのを忘れない。
ちょっと探すのに手間取ったのでメモっておく。
最近はmysqlでデータベースを作ることが多かったんだけど、ちょっとしたもの作るのにmysqlはでかすぎるなあとSQLite+DBICをさわり始めてる。
サンプルはPerl/DBIC - Nekokak's core dumpが、よくまとまっていて非常にわかりやすかったので、これの流れで書いた。が、二箇所ほど悩んだのでメモ。ちなみに、SQLiteのせいかどうかはわかりません。
ちなみに、
というバージョン。
1:多の関係を試す をSQLiteで試す。
まずsqlはこんな感じ
create table user ( id integer PRIMARY KEY not null, name varchar(256) not null, time date ); create table bookmark ( id integer NOT NULL PRIMARY KEY, user_id integer NOT NULL, url text NOT NULL, FOREIGN KEY (user_id) REFERENCES user(id) ); CREATE INDEX user_id_idx ON bookmark (user_id);
で、データベース作成
sqlite3 kzfm.db < test.sql
Schema,User,Bookmarkモジュールはほとんど同じだがload_componentsにPK::Auto::SQLiteを使う。
use strict; use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components(qw/ PK::Auto::SQLite Core/); __PACKAGE__->table('user'); __PACKAGE__->add_columns(qw/id name/); __PACKAGE__->set_primary_key('id'); __PACKAGE__->has_many(bookmark => 'Kzfm::Schema::Bookmark', 'user_id'); 1;
こんな感じ。
で、実行してみると、、、
my $i = $schema->resultset('User')->create({name => 'kzfm'}); $schema->resultset('Bookmark')->create({ user_id => $i->last_insert_id , url => 'http://test.com/'} );
last_insert_idがないと言われた。単にidだけでよいのか?
のとこでUser,Loginお互いにmight_haveを指定すると->idでIDがゲットできなかった。
use strict; use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components(qw/ PK::Auto::SQLite Core/); __PACKAGE__->table('user'); __PACKAGE__->add_columns(qw/id name/); __PACKAGE__->set_primary_key('id'); __PACKAGE__->has_many(bookmark => 'Kzfm::Schema::Bookmark', 'user_id'); #__PACKAGE__->might_have(id => 'Kzfm::Schema::Login'); 1; package Kzfm::Schema::Login; use strict; use warnings; use base 'DBIx::Class'; use DateTime::Format::MySQL; __PACKAGE__->load_components(qw/PK::Auto::SQLite Core/); __PACKAGE__->table('login'); __PACKAGE__->add_columns(qw/id login_time/); __PACKAGE__->set_primary_key('id'); __PACKAGE__->might_have(id => 'Kzfm::Schema::User'); __PACKAGE__->inflate_column('login_time', { inflate => sub { DateTime::Format::MySQL->parse_datetime(shift); }, deflate => sub { DateTime::Format::MySQL->format_datetime(shift); }, });
幾つかのパターンを試した結果、参照するほうにmight_haveをつけるらしい。あと、SQLiteの場合日付まわりをどう処理すればいいのかよくわかってない。とりあえずMySQLのフォーマットでも動くような気がするんだけど。
というわけで、時間のあるうち(気力のあるうち?)に、多対多まではいっときたい。