[Dbix-class] Populate and related tables

Lianna Eeftinck liannaee at gmail.com
Tue May 13 08:35:36 GMT 2014


I'm not sure if it qualifies as a bug; it should probably be
documented at the very least. In void context, the code
(lib/DBIx/Class/ResultSet.pm, sub populate) is pretty obviously only
looking at the first item of its input.

On 13 May 2014 02:20, Louis Erickson <lerickson at rdwarf.net> wrote:
> First, thank you for saying so, Hailin, I'd never have thought to look.
>
> You don't even have to assign it to a variable you don't want; you can just call it in scalar context with 'scalar'.
>
> Second, with three minutes of brainpower I can answer my own question:  Populate does something quite different in scalar or list context than it does in void context.
>
> In scalar or list context, it calls create on each item; it isn't a bulk insert at all.
>
> In void context, it builds a single data item to do the bulk insert with, and has to handle the relationships itself.  It only considers the relationships from the first data item, and uses those relationships for all the data items in the list.
>
> The assumption seems to be that all your items have the same structure, and will all refer to the same relationships - that isn't described, so I'm guessing there.
>
> The documentation points out the internal difference between the different contexts, but I hadn't twigged to the fact that it would handle relationships differently.
>
> On May 12, 2014, at 6:08 PM, Louis Erickson <lerickson at rdwarf.net> wrote:
>
>> I know context can matter, but I would never have expected it to in this case.  I would never have thought to try capturing the return value to change the result.
>>
>> Does anyone know if that's a deliberate difference or is this an unexpected behavior?
>>
>> On May 11, 2014, at 9:35 AM, Hailin Hu <i at h2l.name> wrote:
>>
>>> Hi,
>>>
>>> populate() seems to determine the data structure from the first one in
>>> the array in void context.
>>> Although you don't need the return value, you can have a try:
>>> my $rs = $schema->resultset('Artist')->populate([...
>>>
>>>
>>> On Sun, May 11, 2014 at 11:38 AM, Louis Erickson <lerickson at rdwarf.net> wrote:
>>>> I've been throwing away some old code and replacing it with
>>>> DeploymentHandler.  All my old hand-written SQL files are being replaced by
>>>> Perl which uses DBIC to populate the database.
>>>>
>>>> One of those functions to populate the database didn't work right.
>>>> Eventually, I boiled it down to an standalone test, which still fails in a
>>>> way I didn't expect.  I'm not sure if I'm doing something wrong, or if I've
>>>> missed something in the docs, or if there's a lurking bug.
>>>>
>>>> What I'm seeing is that if I call populate() with a data structure where the
>>>> first item does not reference other tables, none of the other items in the
>>>> data structure will create items in referenced tables.  If the first item
>>>> does refer to other tables, all other references will get created as I
>>>> expected.
>>>>
>>>> My sample has two simple tables:
>>>>
>>>> package TestDb::Schema::Result::Artist;
>>>>
>>>> use Moose;
>>>> use MooseX::NonMoose;
>>>> use MooseX::MarkAsMethods autoclean => 1;
>>>> extends 'DBIx::Class::Core';
>>>>
>>>> __PACKAGE__->table ('artist');
>>>>
>>>> __PACKAGE__->add_columns (
>>>> id => {
>>>>   data_type => 'int',
>>>>   is_auto_increment => 1,
>>>> },
>>>> name => {
>>>>   data_type => 'varchar',
>>>> },
>>>> );
>>>>
>>>> __PACKAGE__->set_primary_key ('id');
>>>>
>>>> __PACKAGE__->has_many (cds => 'TestDb::Schema::Result::CD', 'artist_id');
>>>>
>>>> __PACKAGE__->meta->make_immutable;
>>>>
>>>> 1;
>>>>
>>>>
>>>> package TestDb::Schema::Result::CD;
>>>>
>>>> use Moose;
>>>> use MooseX::NonMoose;
>>>> use MooseX::MarkAsMethods autoclean => 1;
>>>> extends 'DBIx::Class::Core';
>>>>
>>>> __PACKAGE__->table ('cd');
>>>>
>>>> __PACKAGE__->add_columns (
>>>> id => {
>>>>   data_type => 'int',
>>>>   is_auto_increment => 1,
>>>> },
>>>> title => {
>>>>   data_type => 'varchar',
>>>> },
>>>> artist_id => {
>>>>   data_type => 'int',
>>>> },
>>>> );
>>>>
>>>> __PACKAGE__->set_primary_key ('id');
>>>>
>>>> __PACKAGE__->belongs_to (artist => 'TestDb::Schema::Result::Artist',
>>>> 'artist_id');
>>>>
>>>> __PACKAGE__->meta->make_immutable;
>>>>
>>>> 1;
>>>>
>>>>
>>>> Simple as I could make it.
>>>>
>>>> When I call populate with data like this, everything works:
>>>>
>>>> $schema->resultset('Artist')->populate([
>>>> {
>>>> name => 'The Beatles',
>>>> cds => [
>>>> { title => "Sgt. Pepper's Lonely Hearts Club Band" },
>>>> { title => "Yellow Submarine" },
>>>> { title => "Rubber Soul" },
>>>> { title => "Meet the Beatles" },
>>>> ],
>>>> },
>>>> {
>>>> name => 'ABBA',
>>>> cds => [
>>>> { title => 'ABBA Gold' },
>>>> { title => 'More ABBA Gold '},
>>>> ],
>>>> },
>>>> { name => 'Anonymous' },
>>>> ]);
>>>>
>>>>
>>>> This creates an artist called "The Beatles", and CDs called "Sgt. Pepper's
>>>> Lonely Hearts Club Band", "Yellow Submarine", "Rubber Soul", and "Meet the
>>>> Beatles", all referring to the right artist_id for the newly-created "The
>>>> Beatles" artist.  An artist called ABBA is created, as are both of those
>>>> greatest hits CDs.  An an "Anonymous" artist is created with no CDs.
>>>>
>>>> Perfect!
>>>>
>>>> But, if I move the {name => 'Anonymous}, first, before any of the others,
>>>> the behavior is quite different.  None of the CDs get created, just the
>>>> artists.  There's no errors, no complaints, just no entries in the related
>>>> tables.
>>>>
>>>> Not what I expected.
>>>>
>>>> Can anyone shed some light on this?  Any thoughts are appreciated!
>>>>
>>>> I have full working code if someone wants me to put a tar file somewhere.
>>>>
>>>>
>>>> _______________________________________________
>>>> 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
>>>
>>> _______________________________________________
>>> 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
>>
>>
>> _______________________________________________
>> 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
>
>
> _______________________________________________
> 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



More information about the DBIx-Class mailing list