[Dbix-class] prefetching and many_to_many

George Hartzell hartzell at alerce.com
Sun Aug 13 21:06:48 CEST 2006


Matt S Trout writes:
 > George Hartzell wrote:
 > > Matt S Trout writes:
 > >  > [...]
 > >  > But wouldn't it be better to make search_related check the prefetch attr and 
 > >  > copy the appropriate stuff from the cache instead?
 > > 
 > > Would that also work on things fetched through has_many relationships?
 > > 
 > > That'd be great!
 > 
 > Eh? The problem we're discussing here is how to make it work for
 > many-many the same way it does for has_many.
 > 
 > Or are you wanting has_manys to work with prefetch in some extra way?

I just want it to work at all, but my situation may well be
pathological.

Unfortunately I can't share my real dataset (NDA) and haven't [yet]
banged up a sample set, so I can't complain.

I was recently surprised that in spite of cache=>1 I was making
repeated trips to the db, but I now understand why.  I somehow
conflated the conversation above with my cache confusion and shot off
the above note before I thought it through.

This message is a pretty accurate description of what I'm trying to do:

  http://lists.rawmode.org/pipermail/dbix-class/2006-August/002149.html

and your help showed me how to use join to do what I want.

The things I'm having trouble with are:

  1) setting cache=>1 on a search on the "top-level" rn rows, then
     using an rn's ->attrs() accessor to get a list of an rn's attrs
     doesn't cause the attrs to be cached, so things like this:

      ($foo) = grep {$_->name eq 'APE'} $rn->attrs;
      ($foo2) = grep {$_->name eq 'POODLE} $rn->attrs;

     causes multiple trips to the db.

     Daniel Westerman and I bounced some mail back and forth and I
     understand what's going on, but I still wish it were
     different... 

  2) if I add a prefetch => ['node', 'control'] it dies in
     DBIx::Class::Row::inflate_result, with the message "Prefetch not
     supported with accessor 'Multi'" (might be 'multi') from the
     throw_exception near the end of the function.

  2') There's also some other funniness going on, e.g. if I avoid the
      above problem by just prefetching nodes with prefetch => 'node'
      (or was it prefetch => ['node'] that worked?)

     The queries I'm asking involve finding rn's that have pairs of
     nodes that meet certain criteria.  If I don't guard against it, I
     get each qualifying rn back twice, once w/ the where clause
     satisfied by the node pair (n1, n2) and once with the where
     clause satisfied by the node pair (n2, n1).  I can fix that by
     adding distinct => 1 or by adding (e.g.) a test that (n1.id <
     n2.id [I already have to be careful to avoid pairs of (n1,
     n1)...].

     That seems to break getting all of the nodes back into the rn.  I
     only seem to get one of them, and I'm assuming that the
     distinctness test is excluding the rest of them.

Again, I apologize for not being able to post a concrete example, and
I will try to cons one up once I make it past a looming milestone.
For now, things work, they're just slower than they need to be.

Thanks,

g.



More information about the Dbix-class mailing list