Thank you, but as I stated before (this is the problem with mailing lists, 
previous references are lost), mine is a one-to-one relationship, so each book 
record has only one content record.

I can´t understand this behavior as an optimization, retrieving a lot of big 
columns...

Even more, I cant create additional "soft" columns to get results from 
calculations because the prefetch tries to retrieve them, and they do not 
exists really in the db.

I case that DBIc can´t do this kind of query, can I do the query somehow and 
retrieve results i a similar objet for TT?

Here is again my whole schema, with the model, the DBIC Trace, the columns, 
etc. I case someone can help:


I started with the Catalyst tutorial, adding just the special elements. The 
problem remains the same.

I have added a new table: contents, to store additional contents for the 
tutorial table books. So we have two tables:

CREATE TABLE IF NOT EXISTS `books` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` text,
  `rating` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


CREATE TABLE IF NOT EXISTS `contents` (
  `id` int(12) NOT NULL,
  `Content_EN` longtext NOT NULL,
  `Content_ES` longtext NOT NULL,
  `Pictures` blob NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



In Schema/Result/Book.pm I have added the relationship 
between books and contents

__PACKAGE__->might_have(
  "the_content",
  "MyApp::Schema::Result::Content",
  { "foreign.id" => "self.id" },
);


And a ResultSet for my test: Schema/ResultSet/Book.pm with the search that I 
will use from the Controller
I have reduced the columns just to 'title' from books and 'content_en' from 
contents 

sub basic_search {
my ($self) = @_;

return $self->search(
{},
{
columns => [qw/ me.title the_content.content_en /],
prefetch => 'the_content',
});
}


In the template I tried commenting and uncommenting the cell that calls 
'content_en' column
<table>
<tr><th>Title</th><th>Rating</th><th>Author(s)</th></tr>
[% # Display each book in a table row %]
[% FOREACH book IN books -%]
  <tr>
<td>[% book.title %]</td>
<!--     <td>[% book.the_content.content_en %]</td> -->
  </tr>
[% END -%]
</table>



So, in the Controller I call my "basic_search" :

sub list :Local {
    my ($self, $c) = @_;
$c->stash(books => [$c->model('DB::Book')->basic_search()]);
    $c->stash(template => 'books/list.tt2');
}



And in the end, this is what I get in the debug window:
- At first it SELECTs me.title, the_content.content_en
fine
- But then it adds all the columns from the prefetched table!!!!

[info] MyApp powered by Catalyst 5.90007
HTTP::Server::PSGI: Accepting connections at http://0:3000/
SELECT me.title, the_content.content_en, the_content.id, 
the_content.content_en, the_content.content_es, the_content.pictures FROM books 
me LEFT JOIN contents the_content ON the_content.id = me.id: 
[info] *** Request 1 (0.000/s) [24182] [Sat Jan  7 12:31:47 2012] ***
[debug] Path is "books/list"
[debug] "GET" request for "books/list" from "88.23.7.72"
[debug] Rendering template "books/list.tt2"
[debug] Response Code: 200; Content-Type: text/html; charset=utf-8; 
Content-Length: 1564
[info] Request took 0.143192s (6.984/s)
.------------------------------------------------------------+-----------.
| Action                                                     | Time      |
+------------------------------------------------------------+-----------+
| /books/list                                                | 0.088956s |
| /end                                                       | 0.048612s |
|  -> MyApp::View::HTML->process                             | 0.047493s |
'------------------------------------------------------------+-----------'


So I found the very same problem that I have in my real application: unwanted 
(and very BIG) columns are called in each request. I can´t see what is calling 
them.

As I stated some emails ago, the real db has an ancient inherited structure 
that can't be changed, (and I think that splitting text and blob columns from 
the main table is not a strange practice...)








________________________________
 De: neil.lunn <[email protected]>
Para: [email protected] 
Enviado: martes 10 de enero de 2012 0:49
Asunto: Re: [Dbix-class] I get only one in a one to one
 

On 10/01/2012 8:09 AM, Miguel Barco wrote: 
But the problem remains the same, because I want to retrieve some columns from 
the main table an some from the related one, so I was told to use Prefetch.
Which is fine as this is basically an optimisation to avoid going back to the 
database engine to call rows from the related table entry.


>
>What I really need is something as simple as this query (that I can use 
>everywhere):
>
>
>SELECT books.title, contents.content_en
>FROM books, contents
>WHERE books.id = 1111
>AND contents.id = 1111
Which is more or less exactly what prefetch is doing for you. Set
    DBIC_TRACE=1 on the command line before starting you app to see what
    is happening.

But what you are basically missing is that your "contents" table is
    the related table. Therefore for each "book" there are *many*
    "contents". So not only are you iterating through the books, you
    need to iterate through the "contents" as well otherwise of course
    you are just accessing the first line. To see the others you call
    the next one, and so on.

So basically you need to stop thinking in terms of the raw sql
    results and start thinking in terms of the objects that are
    represented. A "book" with many "contents" Which is what an ORM is
    for.
_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/[email protected]

Reply via email to