URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID8
Нить номер: 7156
[ Назад ]

Исходное сообщение
"Ctalyst DBIx вывод в JSON"

Отправлено Azudim , 25-Фев-11 20:54 

Подскажите пожалуйста решение для задачки:

Дано: DBIx shema DB
      View TT
      View JSON

Надо: передать данные из DBIx model('DB::Table') в View::JSON
      или другим способом из DBIx в JSON.
      

Пробую скормить результат в JSON - ругается:

Caught exception in TM::View::JSON->process "encountered object 'TM::Model::DB::Table=HASH(0x56cce00)', but neither allow_blessed nor convert_blessed settings are enabled

Делается все для ajax запросов.

Буду очень признателен, если кто нибудь оставит контакт для консультации.
Спасибо!


Содержание

Сообщения в этом обсуждении
"Ctalyst DBIx вывод в JSON"
Отправлено sm00th1980 , 26-Фев-11 11:49 
делал подобное но только на питоне - по нему могу проконсультировать.

Но в целом подход был такой:
база данных подключалась через ORM(думаю для Perl тоже есть свой ORM) и уже построчно из таблицы данные конвертились в JSON и отдавались(тоже кстати для AJAX).

Пример как раз можно глянуть тут:
http://www.youtube.com/watch?v=FcB8_s-_Iz8


"Ctalyst DBIx вывод в JSON"
Отправлено Azudim , 26-Фев-11 12:25 

Именно такой пример мне и нужен был, но боюсь с питона (Django?) на Каталист не смогу перевести. У Каталиста тоже свой ORM (DBIx::Class), и с выводом в шаблонизатор проблем нет, но шаблонизатор работает с данными из базы как объектами и методами, а Json модуль нет.


P.S. Надеюсь со временем осилить Django, обращусь за консультацией =)


"Ctalyst DBIx вывод в JSON"
Отправлено sm00th1980 , 26-Фев-11 12:41 
>  Именно такой пример мне и нужен был, но боюсь с питона
> (Django?) на Каталист не смогу перевести. У Каталиста тоже свой ORM
> (DBIx::Class), и с выводом в шаблонизатор проблем нет, но шаблонизатор работает
> с данными из базы как объектами и методами, а Json модуль
> нет.
> P.S. Надеюсь со временем осилить Django, обращусь за консультацией =)

я так подозреваю что проблема вот в чём:
ты получаешь рекорды из базы в виде объектов. А JSON-сериализатор ожидает на вход ассоциативный массив(по-моему в perl - это хешем называют).

Ну так вот как ты получишь свой рекорд-объект - в котором в виде свойств будут колонки этого рекорда - сделай из него хеш и уже хеш скорми сериализатору. По идее должно прокатить. Но это по идее.



"Ctalyst DBIx вывод в JSON"
Отправлено Azudim , 26-Фев-11 13:04 
> я так подозреваю что проблема вот в чём:
> ты получаешь рекорды из базы в виде объектов. А JSON-сериализатор ожидает на
> вход ассоциативный массив(по-моему в perl - это хешем называют).

Да! =)

> Ну так вот как ты получишь свой рекорд-объект - в котором в
> виде свойств будут колонки этого рекорда - сделай из него хеш
> и уже хеш скорми сериализатору. По идее должно прокатить. Но это
> по идее.

Вот это то у меня и не получается сделать =(


"Ctalyst DBIx вывод в JSON"
Отправлено sm00th1980 , 26-Фев-11 13:24 
давай этот код в студию - попробую вспомнить былое на великом и могучем perl :)

"Ctalyst DBIx вывод в JSON"
Отправлено Azudim , 26-Фев-11 18:48 
package TM::Controller::Firm;

use strict;
use warnings;
use parent 'Catalyst::Controller';

sub index :Path :Args(0) {
    my ( $self, $c ) = @_;

        # Выводим данные из схемы: join из двух таблиц, связи прописаны в схеме.
        my $rs = $c->model('DB::Firm');
    my @firms = $rs->search(undef,
            {
                '+select'  => [ 'people.nick_name','people.s_name' ],
                join => 'people'  }
            );
        $c->stash->{json} = \@firms;
    $c->forward('View::JSON');

        # Если хотим вывести в Template Toolkit (View:TT)
        # $c->stash(template => 'firm/firm_list.tt');
}
1;

===================== firm_list.tt ===========
[% WRAPPER tpl/header.tt title = c.config.name ; END %]
[% FOREACH firm IN firms -%]
          <tr>
            <td>[% firm.id %]</td>
            <td>[% firm.short_name %]</td>
            <td>[% firm.people.s_name %][[% firm.people.nick_name %]]</td>
          </tr>
[% END -%]
================================================

Если отдаем \@firms в View::JSON - проблема с сериализацией bless'нутых объектов.


"Ctalyst DBIx вывод в JSON"
Отправлено Azudim , 27-Фев-11 13:14 
Вот так уже почти получилось - JSON не ругается, но кодировка где то недоделана.
=========================================
package TM::Controller::Firm;

use strict;
use warnings;
use parent 'Catalyst::Controller';

sub index :Path :Args(0) {
    my ( $self, $c ) = @_;
    my $time = "Текущее время:".localtime;
    # ЗАпрос в
    my $rs = $c->model('DB::Firm');
    my $firms = $rs->search(undef,
            {
                '+select'  => [ 'people.nick_name','people.s_name' ],
                join => 'people'  }
            );
    my (@data, %json);
    while (my $f = $firms->next) {
        my %row;
        $row{short_name} = $f->short_name;
        push @data,\%row;
    }
    
    #foreach my $val (@data) { #print "\n data val: $val";}
    $json{rettext} = "good";
    $json{data} = \@data;
    $c->stash->{json} = \%json;
    $c->forward('View::JSON');
}
1;
==============================
  Вывод:
{
   "json" : {
      "data" : [
         {
            "short_name" : "??????-31"
         },
         {
            "short_name" : "???????"
         },
         {
            "short_name" : "???-?????"
         },
         {
            "short_name" : "???"
         },
         {
            "short_name" : "?????????"
         },
         {
            "short_name" : "???????"
         },
         {
            "short_name" : "???????"
         },
         {
            "short_name" : "????????"
         },
         {
            "short_name" : "?????"
         }
      ],
      "rettext" : "good"
   }
}
В MySQL лежит latin1.
если в Template Toolkit передавать выборку - с кодировкой нет проблем :/


"Ctalyst DBIx вывод в JSON"
Отправлено Azudim , 28-Фев-11 12:54 
Проблема с кодировкой решилась
-------------
package TM::Controller::Ajax;

use strict;
use warnings;
use parent 'Catalyst::Controller';

sub index :Path :Args {
    my($self, $c, @args) = @_;
    my $rs = $c->model('DB::Firms');
    my $firms = $rs->search(undef,
            {
                '+select'  => [ 'people.nick_name','people.s_name' ],
                join => 'people'  }
            );
    ### Исходные данные - список задействованных столбцов
    my $source = $rs->result_source;
    my @column_names = $source->columns;
    #

    my (@data, %json);
    while (my $f = $firms->next) {
        my %row;
        foreach my $col (@column_names) {
            $row{$col} = $f->$col;
            Encode::from_to($row{$col}, 'cp1251', 'utf8');    # кодируем в cp1251, потому что в базе лежит в cp1251    
        }
        push @data,\%row;
    }
    $json{data} = \@data;
    $json{result} = "ok";
    $c->stash->{json} = \%json;
    $c->forward('View::JSON');
}