我有一个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
答案 0 :(得分:0)
第一个条目没有$ sequence的值,所以我会以这种方式重构你的代码:
if(/^>(.+?)/) {
$header=$1;
} else{
$sequence = $_;
$dbh->do("INSERT INTO genes VALUES(?, ?)", undef, $header, $sequence );
}
注意$ dbh-&gt; do语法,这种模式避免了sql注入问题
答案 1 :(得分:0)
我认为你在while循环中的语句顺序是不正常的。并且您需要添加chomp
来删除新行(除非您打算保留它们)。
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循环后添加最后$ dbh-&gt;以获取最后一条记录。