众所周知, DBIx :: Class :: ResultSet 中的 populate()方法提供了高效的批量插入。
但是,我们还需要获取插入记录的标识以供进一步处理。
我们有这样的事情:
my @created_records = $self->schema->instrument_rs->populate(\@records_to_create_rs);
foreach my $record ( @created_records ) {
$id_of->{ $record->Name } = $record->Id;
}
但是,当populate()用于非void 上下文时,在这种情况下列出上下文,它只是作为create()方法的包装器而不是有效的批量插入
鉴于此限制,您建议使用DBIx :: Class :: ResultSet :: populate()来批量插入身份记录的最佳方法是什么?
答案 0 :(得分:2)
如果您有自动递增的主键,
并且没有其他插入同时进行,
它不是简单地批量插入N-1记录,然后通过普通创建插入最后一个?
例如(为我工作):
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 );
编辑:如果你想检查插入是否按照计划进行(而不是确保插入,或者无论如何),可以通过移动和插入第一个信息并比较id计数是否关闭来扩展。如果是,该方法可以默认通过搜索获得记录(然后没有速度增益,抱歉),如果不是,一切顺利,我们就完成了。
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 } ];
}
我实际上将第一个版本放入我的add_to方法之一(给定数组,bulk_insert),到目前为止似乎工作正常。
我会测试那些日子的第二个版本并报告它是否失败......
答案 1 :(得分:0)
这就是我所做的,但@bytepusher的答案似乎更有效率。张贴所有可能答案的文件。
$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);