shoorick: (Default)
Видимо, я ничё не понимаю в ORM вообще и DBIx::Class в частности.
Элементарная для чистого SQL задача: вывести отсортированный по алфавиту список людей может решаться, например, таким запросом:
SELECT CONCAT_WS(' ', lname, fname, sname) AS name
FROM user
ORDER BY name;
Попытки перевести этот запрос на DBIx::Class — сплошь и рядом безуспешные, не помогает ни бубен, ни чтение мануала. Точнее, чтение мануала помогло лишь в одном, понять, что атрибут as ничего не делает. Гугление тоже не особо помогает... По каким принципам в DBIx::Class используются всякие \, [] и {} — тоже не ясно, складывается ощущение, что как попало.

upd/16:50: Из всех методов один даёт почти такой запрос, какой надо. Но как странно это выглядит!
$c->model('Dbase::User')->search(
    {},
    {
        'select'   => [ { '' => \q{CONCAT_WS(' ', lname, fname, sname)}, -as => 'name' } ],
        'order_by' => [ 'name' ],
    }
)
upd/вечернее: Атрибут as всё-таки нужен. Но не для влияния на SQL (он на него не влияет), а для явного указания дбикс-классу имени нового поля.
'select' => [ 'id', { '' => \q{CONCAT_WS(' ', lname, fname, sname)}, -as => 'name' } ],
'as'     => [qw( id name )],
Если его не указать, то появляются сообщение об ошибке: «Метод name не существует».
shoorick: (Default)
Ускоряем каталистовый сайт, переписываем слишком медленные запросы с DBIx::Class на обычный DBI. Попутно допилил напильником каталистовую модель, чтобы она поддерживала UTF-8 в MySQL, о чём и написал в [livejournal.com profile] ru_catalyst. Кому надо — пользуйтесь.
shoorick: (Default)
Это я такое написал? Проще уж на обычном SQL писать...
$c->stash->{'checkpoints'} = [
    $c->model($MODEL)->search(
        {
            'stgroup_id.id'           => $student->stgroup_id->id,
            'checkresults.student_id' => [ $student->id, undef ],
        },
        {
            'select'   => [ \'me.name cpname', qw/me.id me.date max_ball/ ],
            'join'      => [
                'checkresults', {
                    'tss_id' => [
                        qw/stgroup_id subject_id/,
                        { 'teacher_id' => 'user_id' }
                    ],
                }
            ],
            '+columns'  => [
                qw/subject_id.name checkresults.ball/,
                qw/user_id.fname user_id.sname user_id.lname/,
            ],
#             '+as'       => [ qw/subject_name ball/ ],
            'order_by'  => [ qw/date/ ],
        },
    )
];
shoorick: (Default)
Пытаюсь воткнуть свежезарелизенное в один из наших проектов. С одной стороны, конечно, надо придерживаться правила «Не сломалось — не чини», но, с другой, если модуль выложен на CPAN и, следовательно, уже не сильно связан с исходным проектом — нет смысла держать дубль. Пока натыкаюсь на ошибки:
Malformed UTF-8 character (unexpected continuation byte 0x80, with no preceding start byte) in pattern match (m//) at /usr/local/lib/perl5/site_perl/5.8.9/Lingua/RU/Inflect.pm line 254.
[error] Caught exception in engine "Wide character in memGzip at /usr/local/lib/perl5/site_perl/5.8.9/Catalyst/Plugin/Compress/Gzip.pm line 36"
Попробовал добавить в проблемный участок вызовы функций encode и decode:
my @name = Lingua::RU::Inflect::inflect_given_name(
    GENITIVE,
    decode('utf8', $student->user_id->lname),
    decode('utf8', $student->user_id->fname),
    decode('utf8', $student->user_id->sname),
);

push @name, shift @name; # ФИО → ИОФ
$c->stash->{'student_genitive'} = encode('utf8', join(' ', @name));
Вроде, заработало, но выглядит паршиво.

Надо бы perlunicode перечитать...
shoorick: (Default)
Пытаюсь, по совету коллег-перловиков, разобраться с префетчингом в DBIx::Class.

Тяжко. Мануал и кукбук весьма обрывочны и противоречивы, а программирование методом научного тыка неэффективно — в редкие моменты, когда сервер не падает, среди SQL-запросов появляются более сложные, с джойнами, но и они дублируются, так что общее число запросов не сокращается.

Чё делать? То ли забить (не вариант, ибо в новом году ожидается трёхкратное возрастание нагрузки на сервер), то ли дальше курить маны в ожидании просветления...

Re: Ой

Dec. 7th, 2009 09:52 pm
shoorick: (Default)
Поглядев на терзание сервера баз данных нашей поделкой, решил попробовать другой метод: DBIx::Class, вроде бы, позволяет выполнять произвольный SQL-запрос. Запрос-то я написал и протестировал, да вот подсунуть его каталисту пока не получается...

Пойду-ка домой, ужинать и читать мануалы.

Ой

Dec. 7th, 2009 05:45 pm
shoorick: (Default)
Прочитал про отладку в DBIx::Class, включил вывод запросов в лог — ужасаюсь: на отображение одной странички ушло 140 (сто сорок!) запросов (среди них — немало повторяющихся). Даже если СУБД и выдаёт результаты из кэша — это всё равно слишком много. Я, конечно, понимаю, что использование ORM может подразумевать некоторое увеличение использования машинных ресурсов в обмен на экономию времени программиста. Но не до такой же степени!
shoorick: (Default)
Захотелось странного — обновить каталист с 5.7 до 5.8: в новом обещали всякий much easer да much faster. Ну и обновил. А до кучи — и остальные перловые модули, что были в портах. В результате и зайцев не спас, и перед партизанами неудобно выяснилось (чё, спрашивается, сразу не посмотрел?), что в портах каталист старый — 5.71001 и после обновления всё загнулось: и свежие, ещё не закоммиченные версии разрабатываемого сайта, и более старые.

Причина крылась в том, что некоторые модули поменялись, а некоторые — вообще стали deprecated, например, Catalyst::Model::DBIC и http://search.cpan.org/perldoc?Catalyst::Plugin::Authentication::Store::DBIC. И в DBIx::Class что-то поломалось.

Решилось пляской с бубном перегенерацией модулей, описывающих структуру базы данных, командой
script/app_create.pl model Dbase DBIC::Schema Dbase create=static dbi:mysql:БД[:хост] логин пароль
При этом модули создались не там, где раньше, а на один уровень глубже — в каталоге Result.

Пробовал задавать create=dynamic, чтобы поменьше получалось — не выходит: сервер не запускается. Пришлось пока остановиться на этом методе. Почитал мануалы, попробовал погуглить — без особого успеха. Домой пришёл лишь в 22:45.

P. S. Видя такой бардак, решил до кучи и перл проапгрейдить до 5.8.9 — проапгрейдил, но наткнулся на очередные грабли: в портах почему-то нет Catalyst::Plugin::RequireSSL — пришлось ставить через perl -MCPAN -e shell.
shoorick: (Default)
Разгребал старые тикеты от разрабатываемого на Catalyst + DBIx::Class проекта, наткнулся на один из: в БД не вставляются файлы, размером больше, чем @@max_allowed_packet (а, наверное, и ещё меньше; в моём случае максимальный размер — около мегабайта), а @@max_allowed_packet на ходу меняться не хочет. Гуглил методы обхода или, например, готовые решения вставки по кускам (ибо самому писать слегка лениво) — в итоге напоролся на DBIx::Class::InflateColumn::File: хранение файлов в файловой системе с доступом к ним через DBIx::Class. Удивительно...
shoorick: (Default)
Жила-была таблица teacher_subject_stgroup и мозолила глаза длиной своего имени и вечным выпиранием его из красивой картинки со структурой базы данных. Но из соседних таблиц можно было запросто обратиться к ней, сказав, например,
$c->stash->{'teacher_subjects'} = $stgroup->teacher_subject_stgroups;
Однако, надоело — переименовал таблицу в tss. Несколько дней потом безуспешно пытался выполнить $stgroup->tsss. И лишь сегодня обнаружил, что надо было искать не tsss, а tsses. Потому что множественное число, а не просто $word . 's'. Lingua::EN::Inflect::Number, однако...
shoorick: (Default)
Пытаюсь понять, как работает many_to_many в DBIx::Class — ни хрена не понятно :-(
Плюс к тому мануалы написаны по-дурацки: вместо того, чтобы подробно описать параметры используемых функций, автор ограничился парой примеров. За что и поимел — вынужден отвечать юзерам, что всё устроено не так, как они понимают.
shoorick: (Default)
Ковыряться в тонне однотипных исходников, пытаясь в редакторе найти нужный кусок и заменить на что-то новое — не наш метод. Наш метод:
sed -e "s/Page/Teacher/g" -e "s/page/teacher/g" -e "s/Subject/Dept/g" -e "s/subject/dept/g" PageSubject.pm > TeacherDept.pm
Хотя подозреваю, что и это — не самый оптимальный из возможных путей.

upd:Таки да, есть ещё более весёлый метод: запустить helper, который сразу генерит всю толпу модулей. Например, так:
script/app_create.pl model Dbase DBIC::Schema Dbase create=static dbi:mysql:БД[:хост] логин пароль
shoorick: (Default)
Почитал на ангельской мове (ибо по-русски чё-то как-то нету) всячину про DBIx::Class и прочий перломаньячизм. Мозг опух и выключился.

Profile

shoorick: (Default)
shoorick

December 2016

S M T W T F S
    1 23
45678910
11121314151617
18 19 2021222324
25262728293031

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 7th, 2025 11:16 pm
Powered by Dreamwidth Studios