[Dbix-class] Complex join problem

Chris Cole chris at compbio.dundee.ac.uk
Wed Jun 10 14:31:34 GMT 2009


Peter Rabbitson wrote:
> Chris Cole wrote:
>> Peter Rabbitson wrote:
>>> You are not prefetching properly somewhere. Yet this is getting extremely
>>> confusing - please start fresh showing a "slow but correct" dbic query
>>> (the entire search chain) and the resulting SQL (presumably the one above).
>> Ok. Sorry for not getting back earlier, I've been sidetracked with
>> something else.
>>
>> The problem stems in trying to retrieve columns from the reads2expt
>> table in a SELECT.
>>
>> The below works as expected:
>>
>> my $schema = DB::Schema->connect();
>> my @data;
>> my @rs = $schema->resultset('DbMatch')->search(
>>    {
>>       expt_id => $dataset,
>>       abundance => {'>' => 1},
>>       type => 'hairpin-miRNA'
>>    },
>>    {
>>       join => [
>>          {         # join on seq_reads -> reads2expt tables
>>             read_id => {
>>                reads2expts => 'read_id'
>>             }
>>          },
>>          'seq_id'  # join db_sequences table.
>>       ]
>>    }
>> );
>>
>> foreach my $hit (@rs) {
>>    push @data, [ $hit->get_column('seq_id'), $hit->match_start ];
>> }
>> return(\@data);
>>
>> The SQL for the above is:
>> SELECT me.seq_id, me.read_id, me.search_id, me.match_start,
>> me.match_end, me.query_start, me.mismatch FROM db_match me  JOIN
>> seq_reads read_id ON read_id.read_id = me.read_id LEFT JOIN reads2expt
>> reads2expts ON reads2expts.read_id = read_id.read_id LEFT JOIN seq_reads
>> read_id_2 ON read_id_2.read_id = reads2expts.read_id  JOIN db_sequences
>> seq_id ON seq_id.seq_id = me.seq_id WHERE ( ( abundance > ? AND expt_id
>> = ? AND type = ? ) ): '1', '1', 'hairpin-miRNA'
>>
>>
>> However, if I want to get the value for the 'abundance' column for each
>> row I need to use a search_related() step, which dramatically slows down
>> the process.
>>
>>
> 
> Read up on this: http://search.cpan.org/~ribasushi/DBIx-Class-0.08103/lib/DBIx/Class/Manual/Cookbook.pod#Using_joins_and_prefetch

Ah, right. Thanks.

The prefetch is working as far as I can tell, but can't seem to access 
the relationship. e.g.

    my $schema = DB::Schema->connect();

    my @data;
    my @rs = $schema->resultset('DbMatch')->search(
       {
          expt_id => $dataset,
          abundance => {'>' => 1},
          type => 'hairpin-miRNA'
       },
       {
          join => [
             {         # join on seq_reads -> reads2expt tables
                read_id => {
                   reads2expts => 'read_id'
                }
             },
             'seq_id'  # join db_sequences table. Need this in order to 
filter by 'type'
          ],
          prefetch => [
             {
               read_id => {
                   reads2expts => 'read_id'
                }
             },
          ]
       },
    );

The SQL from this is:
SELECT me.seq_id, me.read_id, me.search_id, me.match_start, 
me.match_end, me.query_start, me.mismatch, read_id.read_id, 
read_id.length, read_id.seq, reads2expts.expt_id, reads2expts.read_id, 
reads2expts.abundance, reads2expts.read_name, read_id_2.read_id, 
read_id_2.length, read_id_2.seq FROM db_match me  JOIN seq_reads read_id 
ON ( read_id.read_id = me.read_id ) LEFT JOIN reads2expt reads2expts ON 
( reads2expts.read_id = read_id.read_id )  JOIN seq_reads read_id_2 ON ( 
read_id_2.read_id = reads2expts.read_id )  JOIN db_sequences seq_id ON ( 
seq_id.seq_id = me.seq_id ) WHERE ( abundance > ? AND expt_id = ? AND 
type = ? ) ORDER BY reads2expts.read_id: '1', '1', 'hairpin-miRNA'

But I can't get the syntax right for accessing the 'abundance' column. 
According to the docs, something like this should work:
foreach my $hit (@rs) {
   push @data, [ $hit->get_column('seq_id'), $hit->match_start, 
$hit->read_id->reads2expts->read_id->abundance ];
}

I've tried lots of different variations of the above to access the 
'abundance' data, but I always get a 'Can't locate object method...' 
error. I really can't see where I going wrong.

Thanks very much for your continued help.
Cheers,

Chris



More information about the DBIx-Class mailing list