Давайте предположим, что у меня есть следующая упрощенная база данных в качестве примера, состоящая из трех таблиц:
CREATE TABLE people (
person_id INTEGER PRIMARY KEY,
person_name VARCHAR(100)
);
CREATE TABLE events (
event_id INTEGER PRIMARY KEY,
event_name VARCHAR(100),
event_creator INTEGER
CONSTRAINT fk_event_creator REFERENCES people(person_id)
);
CREATE TABLE event_attendees (
event_id INTEGER NOT NULL
CONSTRAINT fk_event_attendee_event
REFERENCES events(event_id),
person_id INTEGER NOT NULL
CONSTRAINT fk_event_attendee_person
REFERENCES people(person_id),
role CHAR(1), -- O: organizer, P: performer, S: speaker, G: guest
CONSTRAINT pk_event_attendees PRIMARY KEY (event_id, person_id)
);
Данный event_id
, Я мог бы хотеть запросить для названий всех организаторов, данных a person_id
Я мог бы хотеть найти названия всех событий, где этот человек является гостем или создателем события так на и т.д.
Я знаю, как сделать весь тот использующий простой SQL. Могли Вы говорить мне, какие классы результата я должен настроить и какие виды отношений я должен указать при использовании DBIx:: Класс?
Are you familiar with DBIx::Class::Schema::Loader? Хотя его можно использовать в одноразовых сценариях для создания схемы DBIC динамически в памяти, он также имеет возможность работать в режиме "one-shot", когда он записывает определения схемы на диск, чтобы вы могли их редактировать и наращивать, и это намного более продвинуто, чем вы можете подумать.
Во-первых, вы хотите, чтобы схема действительно присутствовала в базе данных, чтобы загрузчик мог ее просканировать. Затем вы делаете что-то вроде:
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"), вы можете решить, что схема в БД является вашим основным источником, и сохранить сценарий Schema::Loader для повторного запуска, чтобы автоматически сгенерировать классы, если БД изменится.
Части приведенной выше схемы не обрабатываются корректно с DBIx::Class::Schema::Loader v0.05002, потому что Синану удалось найти ошибку! Ограничения внешнего ключа не обрабатывались корректно, если часть "references" и имя столбца не находились в одной строке.
Ошибка исправлена в DBICSL git, но поскольку исправление еще не выпущено, вот как должны выглядеть отношения (я опускаю определения столбцов для экономии места; они должны быть такими, какими их сейчас генерирует загрузчик).
__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" },
{}
);
__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"
);
__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"
);