简体   繁体   English

获取使用DBIx :: Class :: ResultSet :: populate()插入的记录的标识的最佳方法是什么?

[英]What is the best way to get identity of records inserted using DBIx::Class::ResultSet::populate()?

As we know, the populate() method in DBIx::Class::ResultSet provides efficient bulk inserts. 众所周知, DBIx :: Class :: ResultSet中populate()方法提供了有效的批量插入。

However, we also need to get the identity of the inserted records for further processing. 但是,我们还需要获取插入记录的标识以进行进一步处理。

We have something like this: 我们有这样的事情:

my @created_records = $self->schema->instrument_rs->populate(\@records_to_create_rs);

foreach my $record ( @created_records ) {
    $id_of->{ $record->Name } = $record->Id;
}

But, when populate() is used in a non-void context, list context in this case, it just acts as a wrapper to the create() method and not as an efficient bulk insert. 但是,在非void上下文中使用populate()时,在这种情况下使用列表上下文时,它只是充当create()方法的包装,而不是有效的批量插入。

Given this limitation, what do you recommend as the best way to get identity records bulk-inserted using DBIx::Class::ResultSet::populate()? 鉴于此限制,您建议使用DBIx :: Class :: ResultSet :: populate()来获得批量插入身份记录的最佳方法是什么?

If you have an auto-incremented primary key, 如果您具有自动递增的主键,
and there are no other insertions going on at the same time, 并且没有其他插入同时进行,
would it not be a solution to simply bulk insert N-1 records, then insert the last via normal create? 简单地批量插入N-1个记录,然后通过正常创建插入最后一个记录,不是一个解决方案吗?

For example ( worked for me ): 例如(为我工作):

my $last_info = pop @records_to_create_rs;
my $items = scalar(@records_to_create_rs);
$rs->populate( \@records_to_create_rs );
my $last = $rs->create( $last_info );
my ( $first_id, $last_id ) = ( $last->id - $items, $last->id );
my @inserted_ids = ( $first_id .. $last_id );

Edit: if you wanted to check whether the insertion went as planned ( instead of ensuring it, or anyway ), one could expand upon this by also shifting and inserting the first info and comparing whether the id count is off. 编辑:如果您想检查插入是否按计划进行(而不是确保进行插入,或者无论如何),则可以通过移动并插入第一个信息并比较ID计数是否为OFF来扩展插入。 If it is, the method could default to get the records via search ( no speed gain then, sorry ), if it is not, all went well and we are done. 如果是,则该方法可以默认通过搜索来获取记录(然后没有速度提高,对不起),如果不是,则一切顺利,我们已经完成了。

my $first_info = shift @records;
my $items = scalar( @records );
my $last_info = pop @records;
$rs->create( $first_info );
$rs->populate( \@records );
my $last = $rs->create( $last_info );
my $expected = $first_id +1;
if ( $expected == $last->id - $items ){
   return [ $first_id .. $last->id ];
}else{
   # get the records another way, I did not check this
   @records = $rs->search( \@records )->all;
   unshift @records, $first;
   push @records, $last;
   return [ map { $_->id } ];
}

I actually put the first version into one of my add_to methods ( given array, bulk_insert ), it appears to be working fine so far. 实际上,我将第一个版本放入了我的一个add_to方法(给定array,bulk_insert)中,到目前为止,它似乎运行良好。

I will test the second version one of those days and report if it fails... 我将在那几天测试第二个版本,并报告是否失败...

This is what I've done but the answer from @bytepusher seems to be more efficient. 这是我所做的,但是@bytepusher的答案似乎更有效。 Posting for documentation of all possible answers. 发布所有可能答案的文档。

$self->schema->instrument_rs->populate(\@records_to_create_rs);

$created_records_rs = $self->schema->instrument_rs->search(
    { 'InstrumentTypeId' => $inst_type_id, },
    { order_by           => { -desc => 'Id' } }
)->slice(0,$records_to_create_count - 1);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM