bulk insertでいろいろはまりはまり。

DBICでbulk insertしようと思ってハマッたわけです。insert into hoge values(1,1) (1,2)みたいなことをDBICでやりたい訳です。

はまった一個目。populateのcontext。DBIx::Class::ResultSetより

Pass an arrayref of hashrefs. Each hashref should be a structure suitable for submitting to a $resultset->create(...) method.

In void context, insert_bulk in DBIx::Class::Storage::DBI is used to insert the data, as this is a faster method.

と書いてある通り、contextがlistかvoidかを見て、動く内容が違う訳です。void contextにしないとbulk insertにならない。
で、試しにCatalystのAppでこんなコードを書いた訳です。

sub import : Local {
    my ($self,$c) = @_;

    $c->model('DBIC::Exhibition')->populate([
        {id=>20,exhibit_name => 'aaaaaa'},
        {id=>21,exhibit_name => 'bbb'}, 
        {id=>22,exhibit_name => 'bbb'}, 
    ]);
}

それでDBIC_TRACEの内容を見ても一行ずつしかinsertされなくておかしいなぁと思ってしばらくして気がつきました。
populateが戻り値になってる!

つまりは一番最後に書いてある文なので、perlは自動で一番最後の文の戻り値をreturnしようとする訳です。
最後の文がpopulateなので、voidじゃなくてlist contextになってしまった。普通に他の文を書き進めてれば良かった話。

これDBICあんまり関係ないな。でもwantarrayを使ってcontextを見ている物は要注意と学習しました。しばらくはまった。


はまりその2。bulk insertはlogに出ない。

環境変数DBIC_TRACEを1にすると、実行されたSQLがログにでて、ここを見ながらDBICを試行錯誤する訳ですが、

INSERT INTO `exhibition` (`exhibit_name`, `id`) VALUES (?, ?): '0', '1'

とだけ出て、一行しか入ってないんじゃないの?って思うんですが、DBを直接見てみると入ってます。困ったら結果は直接見ろ、ですな。


いまはdebugだからhard codeでいいけど実際IDどこから持ってくるんだろうか。$rs->first->idとかでいいのかなぁ。