0

我有一个 FASTA 文件如下

>header1
AAAAA
AAA
>header2
BBBBB

我已经能够使用 DBI 通过 perl 创建一个 SQLite 表。

#!/usr/bin/perl
use strict;
use warnings;
use DBI;

my $dbh = DBI->connect( "DBI:SQLite:dbname=gene.db" , "" , "" ,
                    { PrintError => 0 , RaiseError => 1 } );
$dbh->do("DROP TABLE IF EXISTS genes");
$dbh->do("CREATE TABLE genes(gene_name VARCHAR(50) PRIMARY KEY, sequence TEXT)");

parse();
sub parse{
my $fasta_file = 'example.faa';
my $header='';
my $sequence='';

open(INPUT, $test_file) || die "ERROR: can't read input file: $!";
    while(<INPUT>){
        if(/^>(.+?)/){
           $header=$1;
          #$dbh->do("INSERT INTO genes VALUES('$header','$sequence')");
           $sequence='';
        }else{
           $sequence.=$_;
        }
     }
}
$dbh->disconnect();

现在我知道$dbh->do("INSERT INTO genes VALUES('$header','$sequence')");会将标题和序列插入数据库,但我遇到了第一个条目的问题,特别是如果第一个条目具有多行序列。第一个条目的顺序似乎被移到了第二个。我试图将$dbh->do语句移到 else 中,但我可能会出错。想法?

sqlite> select * from Genes;
header      sequence
----------  ----------  
header1      
header2     AAAAAAAA

如果我将do()语句放在else子句中,我会收到以下错误。

DBD::SQLite::db do failed: column header is not unique
4

2 回答 2

0

第一个条目对 $sequence 没有任何价值,所以我会以这种方式重构您的代码:

if(/^>(.+?)/) {
   $header=$1;

} else{
   $sequence = $_;
   $dbh->do("INSERT INTO genes VALUES(?, ?)", undef, $header, $sequence );  
}

注意 $dbh->do 语法,这种模式避免了 sql 注入问题

于 2013-03-05T22:12:48.197 回答
0

我认为您在 while 循环中的语句顺序不正确。并且您需要添加 achomp来删除新行(除非您打算保留它们)。

open(INPUT, $test_file) || die "ERROR: can't read input file: $!";
    while(<INPUT>){
        chomp;
        if(/^>(.+)/){
            $dbh->do("INSERT INTO genes VALUES('$header','$sequence')") if $sequence;
            $header=$1;
            $sequence='';
        }else{
           $sequence.=$_;
        }
     }
     $dbh->do("INSERT INTO genes VALUES('$header','$sequence')") if $sequence;

         }

更新:在 while 循环之后添加了 last $dbh->do 以获取最后一条记录。

于 2013-03-06T00:56:22.430 回答