[Dbix-class] prefetch across multiple tables
Lasse Makholm
lasse at unity3d.com
Wed Dec 17 22:36:31 GMT 2014
On Wed, Dec 17, 2014 at 7:39 PM, John Stoffel <john at stoffel.org> wrote:
>
>
> Hi all,
>
> With a bit of nudging, I had a head-smack moment and upgraded to the
> latest version of DBIx::Class on CPAN, and it now looks like things
> are working better for me, but I'm still getting some interesting
> behavior.
>
> Before I got errors, now I can do:
>
> > ../bin/dbic-test.pl Emlen
> DBIx::Class::ResultSet::_construct_results(): Unable to properly
> collapse has_many results in iterator mode due to order criteria -
> performed an eager cursor slurp underneath. Consider using ->all() instead
> at ../bin/dbic-test.pl line 20
>
Do you have proper non-nullable primary keys set up in all the relevant
result classes?
> Full Name: Emlen & Howell (8213)
> account_id=5920 boxfolder_id=234 URL: b16f10
> account_id=5921 boxfolder_id=249 URL: b17f10
> account_id=5922 boxfolder_id=281 URL: b19f12
> Full Name: Emlen, Caleb (8214)
> account_id=5923 boxfolder_id=14 URL: b01f14
> account_id=5924 boxfolder_id=50 URL: b04f05
>
>
> So I think I need to change my loop from:
>
> while (my $r = $rs->next) {
> print "Full Name: ", $r->full_name, " (", $r->name_id, ")\n";
>
> foreach my $a ($r->account()) {
> print " account_id=", $a->account_id();
> print " boxfolder_id=",$a->boxfolder_id()," ";
> my $t = $a->url();
> $t =~ m/value2=(\w+)\&/;
> print " URL: $1";
> $vol = $a->boxfolder->volume;
> $folder = $a->boxfolder->volume;
> $range = $a->boxfolder->range;
> print " V=$vol " if defined $vol;
> print " F=$folder " if defined $folder;
> print " R=$range " if defined $range;
>
> print "\n";
> }
> }
>
>
> To something more like this:
>
> my @r = $rs->all
> foreach my $r (@r) {
>
Be aware that this will cost you in terms of memory because you'll inflate
all row objects once. Especially if you prefetch a lot... Depending on your
specific result sets, this may not matter to you... But it's definitely
something to be aware of...
We've seen lots of worker processes gobble up 50 - 100 MB of extra memory
because of this, so we've been converting most uses of foreach my $row
($rs->all) { ... } to while (my $row = $rs->next) { ... }. YMMV.
/L
> print "Full Name: ", $r->full_name, " (", $r->name_id, ")\n";
>
> foreach my $a ($r->account()) {
> print " account_id=", $a->account_id();
> print " boxfolder_id=",$a->boxfolder_id()," ";
> my $t = $a->url();
> $t =~ m/value2=(\w+)\&/;
> print " URL: $1";
> $vol = $a->boxfolder->volume;
> $folder = $a->boxfolder->volume;
> $range = $a->boxfolder->range;
> print " V=$vol " if defined $vol;
> print " F=$folder " if defined $folder;
> print " R=$range " if defined $range;
>
> print "\n";
> }
> }
>
> And that does seem to do the trick. Now to move onto updating my
> Dancer web interface and see if I'm getting proper data out (or that I
> even have proper data IN!) of the DB and displayed nicely for the end
> users.
>
> Thanks for the help, I feel a little dumb for not thinking to upgrade
> right off the bat.
>
> Cheers,
> John
>
> _______________________________________________
> 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/dbix-class@lists.scsys.co.uk
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.scsys.co.uk/pipermail/dbix-class/attachments/20141217/516df16c/attachment.htm>
More information about the DBIx-Class
mailing list