[Dbix-class] Re: Prefetch and join on different tables
Peter Rabbitson
rabbit+dbic at rabbit.us
Tue Jan 22 18:21:22 GMT 2013
On Tue, Jan 22, 2013 at 02:46:40PM -0300, Paula wrote:
> OK this is the code: (in previous emails I used different names for the
> tables to simplify them, here I am using the real names in my code:
> molcfp=mc,molstat=mt,moldata=mdata)
>
>
> $attr->{join}='molstat';
> $attr->{prefetch}='molcfp';
> @molstats=split(/;/,$molstat);
> foreach my $i (@molstats) {
> my @split_molstats=split(/:/,$i);
> my $a=$split_molstats[0];
> my $b=$split_molstats[1];
> $where->{"molstat." ."$a"}= [ -and => {'>=',int($b*$minval)},
> {'<=',int($b*$maxval)}];
> }
> foreach my $i (@molcfp_hfps) {
> my $num_hfp;
> my @split_molcfp_hfps=split(/,/,$i);
> if ($cont2 <10) {$num_hfp="hfp0" . $cont2;}
> if ($cont2 >= 10) {$num_hfp="hfp" . $cont2;}
> $n1 = unpack("B32", pack("N", $i));
> $n1= ($n1=~ tr/1//);
> for (my $j=1;$j<=16;$j++){
> $hfp[$j]=$molcfp_hfps[$j-1];
> }
> $a_sum=$n1bits_q;
> $i=int($i);
> if ($n1>3) {$where-> {"molcfp." . "$num_hfp"}={"& $i >" ,'0'}};
> $cont2++;
> }
> if ($n1bits_q>0) {
> $where-> {'molcfp.n_h1bits'} =
> [-and=>{'>=',$punto_de_corte*$n1bits_q},{'<=',(1/$punto_de_corte)*$n1bits_q}];
> }
> my $rs1 = $c->model('weight::Moldata')->search($where,$attr); (this line
> can vary according to the different alternatives I tried)
>
> while ($cand = $rs1->next()) {
^^ $cand here is still an object of the 'Moldata' result class.
> $hfp01 = $cand-> get_column('hfp01');
> $hfp02 = $cand-> get_column('hfp02');
> $hfp03 = $cand-> get_column('hfp03');
> $hfp04 = $cand-> get_column('hfp04');
> $hfp05 = $cand-> get_column('hfp05');
> $hfp06 = $cand-> get_column('hfp06');
> $hfp07 = $cand-> get_column('hfp07');
> $hfp08 = $cand-> get_column('hfp08');
> $hfp09 = $cand-> get_column('hfp09');
> $hfp10 = $cand-> get_column('hfp10');
> $hfp11 = $cand-> get_column('hfp11');
> $hfp12 = $cand-> get_column('hfp12');
> $hfp13 = $cand-> get_column('hfp13');
> $hfp14 = $cand-> get_column('hfp14');
> $hfp15 = $cand-> get_column('hfp15');
> $hfp16 = $cand-> get_column('hfp16');
^^ these columns are part of the Molcfp result source. You can not
access them from the Moldata class (think for a minute how that would
work if both Moldata and Molcfp had columns named 'hfp01').
Also Molcfp is a has-many. If you pay attention the amount of Moldata
"$cand"s you get back is equal to the amount of rows in Moldata, it is
not a cross-product of Moldata * Molstat * Molcfp.
Instead what prefetch does is build you a hierarchy of objects. With or
without specifying it you can do:
for $cand ... {
my $molcfps = $cand->molcfp;
for my $molcfp ($molcfps->all) {
...
}
}
The only thing that prefetch gives you is that the extra "drilling down"
the relationship tree does not fetch more data from the database.
Everything happens in one query. See [1] for more info and don't
hesitate to ask more questions if things aren't clear.
[1] https://metacpan.org/module/GETTY/DBIx-Class-0.08204/lib/DBIx/Class/Manual/Joining.pod#FETCHING-RELATED-DATA
Cheers
More information about the DBIx-Class
mailing list