DBIx::Class::Schema::Loaderに精通していますか? ワンオフ スクリプトで DBIC スキーマをメモリ内に動的に作成するために使用できますが、スキーマ定義をディスクに書き込んで編集および構築できる「ワンショット」モードで実行することもできます。そして、それはあなたが思っているよりもはるかに進んでいます。
まず、ローダーがスキーマをスキャンできるように、スキーマをデータベースに実際に存在させたいと考えています。次に、次のようなことを行います。
perl -MDBIx::Class::Schema::Loader=make_schema_at \
-e 'make_schema_at("MyApp::Schema", {dump_directory=>"schema_out"},' \
-e '["dbi:DBType:connstring", "user", "pass"]);'
(ここで、「MyApp::Schema」は、生成されたスキーマ クラスで共有するパッケージ名であり、「schema_out」は、それらを生成するディレクトリです)。
この後、生成されたスキーマ クラスを編集できます。または、ローダーが十分な仕事をしていることがわかった場合 (または、少なくとも "DON'T EDIT ABOVE THIS LINE" 行)、DB 内のスキーマがプライマリ ソースであると判断し、Schema::Loader スクリプトを保存して、DB が変更された場合にクラスを自動的に再生成するために再度実行することができます。
アップデート
上記のスキーマの一部は DBIx::Class::Schema::Loader v0.05002 で正しく処理されません。Sinan がバグを発見したからです! 「参照」部分と列名が同じ行にない場合、外部キー制約が正しく解析されませんでした。
バグは DBICSL git で修正されていますが、修正がまだリリースされていないため、リレーションは次のようになります (スペースを節約するために列の定義を省略しています。現在ローダーが生成しているものと同じにする必要があります)。
EventAttendee.pm
__PACKAGE__->set_primary_key(qw(event_id person_id));
__PACKAGE__->belongs_to(
"event" => "MyApp::Schema::Result::Event",
{ event_id => "event_id" },
{}
);
__PACKAGE__->belongs_to(
"person" => "MyApp::Schema::Result::Person",
{ person_id => "person_id" },
{}
);
イベント.pm
__PACKAGE__->set_primary_key("event_id");
__PACKAGE__->belongs_to(
"event_creator" => "MyApp::Schema::Result::Person",
{ person_id => "event_creator" },
{ join_type => "LEFT" },
);
__PACKAGE__->has_many(
"event_attendees" => "MyApp::Schema::Result::EventAttendee",
{ "foreign.event_id" => "self.event_id" },
);
# Not auto-generated, but you probably want to add it :)
__PACKAGE__->many_to_many(
"people_attending" => "event_attendees" => "person"
);
People.pm
__PACKAGE__->has_many(
# It might be wise to change this to "events_created"
"events" => "MyApp::Schema::Result::Event",
{ "foreign.event_creator" => "self.person_id" },
);
__PACKAGE__->has_many(
"event_attendees" => "MyApp::Schema::Result::EventAttendee",
{ "foreign.person_id" => "self.person_id" },
);
# Not auto-generated, but you probably want to add it :)
__PACKAGE__->many_to_many(
"events_attending" => "event_attendees" => "event"
);