DBIx::Class, dbicdump и префикс таблицы

У меня есть база данных MySQL (MariaDB) с несколькими таблицами внутри. Все имена таблиц имеют префикс, например app_author, app_album, app_track (на самом деле, существуют разные таблицы, но здесь можно использовать пример с автором-альбомом-треком). Я использую dbicdump, чтобы сбросить структуру моей БД. Проблема в том, что сгенерированные наборы результатов называются AppAuthor, AppAlbum, AppTrack. Мои определенные отношения между таблицей и таблицей, на которую ссылаются, называются столбцами в этих таблицах, другой способ называется таблицами.

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

create table app_author (
  id int not null,
  name varchar(255),
  primary key(id)
);
create table app_album (
  id int not null,
  name varchar(255),
  author int not null references app_author (id),
  primary key (id)
);
create table app_track (
  id int not null,
  name varchar(255),
  album int not null references app_album (id),
  primary key(id)
);

И пример использования в Perl будет таким:

my $album = resultset("AppAlbum")->search(...)->single; # [1]
my $author = $album->author;
for my $track ($album->app_tracks) { # [2]
...
}

Мои вопросы:

  1. Есть ли возможность указать dbicdump игнорировать эти префиксы «app_» и создавать наборы результатов с именами без них, например Author, Album, Track?

  2. Как автоматически создавать отношения без префикса «app_»?

Я знаю, что мог бы создавать наборы результатов вручную, но тогда мне нужно было бы вручную синхронизировать БД с моей моделью БД каждый раз, когда я меняю БД (что довольно часто происходит на текущем этапе реализации приложения). Я бы предпочел некоторую настройку dbicdump для автоматизации этого, но мне не удалось найти это в документации.

В настоящее время я использую это в своем коде:

my $PREFIX = "app_";
...
my $album = resultset("${PREFIX}Album")->search(...)

А также в классах результирующего набора, сгенерированных dbicdump, я всегда добавляю «правильные» отношения, подобные этим, чтобы можно было использовать $album->tracks:

package MyApp::DB::Result::AppAlbum;
...
# Created by DBIx::Class::Schema::Loader v0.07052 @ 2024-05-21 11:41:20
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:TvdTvR2Iuo++AHLi0SHc3g

sub tracks ($self)
{
    return $self->app_tracks;
}

Спасибо за ваши советы.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Да, именование можно настраивать, см. https://metacpan.org/pod/DBIx::Class::Schema::Loader::Base#naming.

Конечно, настраивается, но полезно ли это для решения проблемы ОП? В связанном разделе я не вижу ничего актуального. Не могли бы вы расширить свой ответ и показать, как это можно сделать?

ikegami 23.05.2024 17:42

@ikegami там много информации, я знал об этом документе. Но этот ответ заставил меня прочитать его еще раз. И я нашел решение там, но не в разделе именования.

ico 24.05.2024 10:47
Ответ принят как подходящий

Наконец я нашел рабочее решение. Нам нужны 2 файла:

Файл db_dump.sh для запуска dbicdump по очереди с желаемой конфигурацией:

#!/bin/sh

export PERL5LIB=../perl5lib/lib/perl5

../perl5lib/bin/dbicdump \
    -o config_file=./db_dump.pm \
    -o dump_directory=./lib \
    MyApp::DB \
    dbi:mysql:database=mydb dbuser dbpass \
    '{ quote_char => "`" }'

Файл db_dump.pm для настройки dbicdump. Я включил версии с хэшрефом и подписями (мои предпочтительные версии):

{
    constraint => '^(?:user|session|app_.*)$',
    moniker_map => sub {
        my ($table, $moniker, $callable) = @_;
        #return "$table"; # $moniker = $table_name
        $moniker =~ s/^App//;
        return $moniker;
    },
#    moniker_map => {
#        app_author => "Author",
#        app_album  => "Album",
#        app_track  => "Track",
#    },
    rel_name_map => sub {
        my ($a, $coderef) = @_;
        return unless $a->{type} eq "has_many";
        $a->{name} =~ s/^app_//;
        return $a->{name};
    },
#    rel_name_map => {
#        Author => { # name all changes to Author's relationships
#            app_albums => "albums",
#        },
#        Album => { # name all changes to Album's relationships
#            app_tracks => "tracks",
#        },
#    },
}

Теперь запустите db_dump.sh, и все классы будут выгружены из БД и помещены в соответствующие файлы в ./lib/MyApp/DB/Result/.

Несколько случайных заметок:

  • Если вы читаете документацию DBIx::Class, прозвище — это имя набора результатов, например resultset($moniker)->search()...

  • -o dump_directory=./lib
    Это должно быть указано в командной строке, указав его в файл конфигурации не работает

  • ограничение
    Regex для указания таблиц для дампа.

  • moniker_map
    1-я форма (хэш-ссылка со схемой) — мне не удалось заставить ее работать.
    2-я форма (хеш-ссылка без схемы) — следует перечислить все интересное. столы. Прекрасно работает.
    3-я форма (coderef). Просто верните желаемое имя для соответствующей таблицы. Или undef по умолчанию. Не понял часть с вызываемым кодом. Легко удалить ненужные префиксы.

  • rel_name_map
    Хэшрефы с никнеймами работают. Но указание всех изменений... тоже много работы.
    Версия coderef — это то, что мне нужно.

Подробнее читайте https://metacpan.org/pod/DBIx::Class::Schema::Loader::Base, там всё есть. На самом деле, там слишком много информации :)

Другие вопросы по теме