Как должен я настраивать свой DBIx:: классы результата Класса в этом простом случае?

Давайте предположим, что у меня есть следующая упрощенная база данных в качестве примера, состоящая из трех таблиц:

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:: Класс?

7
задан Sinan Ünür 18 February 2010 в 18:07
поделиться

1 ответ

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, но поскольку исправление еще не выпущено, вот как должны выглядеть отношения (я опускаю определения столбцов для экономии места; они должны быть такими, какими их сейчас генерирует загрузчик).

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" },
    {}
);

Event.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"
);
6
ответ дан 7 December 2019 в 10:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: