[Dbix-class] Possible problem with prefetch

Will Hawes info at whawes.co.uk
Mon Apr 3 12:23:52 CEST 2006


luke saunders wrote:
> Is this the expected behaviour of prefetch? Apologies for not replacing 
> all the names with 'foo', 'bar' etc.
> 
> Receptor has a 'many to many' relationship with Ligand, with 
> 'natural_ligands_map' being the bridging relationship.
> 
> I want to preform a search on Receptor which prefetches all the Ligand 
> rows. So I do the following:
> 
>     my $rs = $c->config->{schema}->resultset('Receptor')->search
>         ({class4 => 'Orphan'},
>          {prefetch => {natural_ligands_map => 'ligand'}});
> 
>     my $count = $rs->count;
>     # $count is 0 here
> 
> The search returned no results despite there being 60 Receptor rows 
> which have a class4 of 'Orphan'. The reason for this is that these 
> receptors don't have any Ligands. Proved by the following :
> 
>     my $rs = $c->config->{schema}->resultset('Receptor')->search
>         ({class4 => 'Orphan'});
> 
>     my $count = $rs->count;
>     # $count is 60 here
> 
> this returns 60 receptors as expected.
> 
> Now, I want the Receptor rows even if they don't have any Ligands but 
> that doesn't appear to be possible. Is this a bug or is it the expected 
> behaviour? If it's a bug I'll knock up a test case for y'all.
> 
> Obviously not doing the prefetch solves the problem but in this case 
> that's much too expensive.
> 
> Thanks,
> Luke.
> 
> Resulting debug SQL from first search for reference (I replaced the 
> column names with * to save space):
> SELECT me.*, natural_ligands_map.*, ligand.* FROM receptors me LEFT JOIN 
> natural_ligands_2_receptors natural_ligands_map ON ( 
> natural_ligands_map.gpcrid = me.gpcrid )  JOIN natural_ligands ligand ON 
> ( ligand.ligid = natural_ligands_map.ligid ) WHERE ( ( ( class4 = ? ) ) 
> ) ORDER BY natural_ligands_map.gpcrid: `Orphan'


If I've read that correctly, you need the natural_ligands_map to 
generate LEFT JOIN rather than JOIN to get the desired behaviour.

That can be specified in your model class for the natural_ligands_map 
table. I'm not 100% on the syntax, but I think it should be something 
like this:

package Your::NaturalLigandsMap::Class';
...
__PACKAGE__->has_many( 'natural_ligands' => 
'Your::NaturalLigands::Class', 'ligid', { join_type => 'left' } );



More information about the Dbix-class mailing list