DBI :: mysql和File :: Temp

时间:2012-04-24 09:48:47

标签: mysql perl dbi temporary-files

我正在尝试使用LOAD DATA LOCAL INFILE语句将数据加载到MySQL数据库中。在普通文件上,这很好。

如果我使用File::Temp创建临时文件,请在其中存储CSV数据,关闭该文件,然后使用

直接LOAD将其存入数据库
$dbh->do("LOAD DATA LOCAL INFILE '$tempfile' INTO TABLE $temptable" FIELDS TERMINATED BY ',');

最后两个记录可重复省略。但是,如果我在创建和LOAD之间对tempfile执行任何操作,例如使用

`touch $tempfile`;

一切都按预期工作。

这是MySQL驱动程序在新创建的临时文件时遇到问题的问题吗?它是一个文件系统(ext4)问题,可能是缓存刷新没有及时发生?我在这里错过了什么吗?

编辑:实际上,如果临时CSV文件不是由格式转换器子程序创建的,则会省略所有记录,但如下所示。我还包括了数据库交互的代码。请注意评论touch $tmpfh,当取消注释时,会使示例正常工作。

UNLINK => 0添加到File::Temp->new()并没有什么区别。

my $tmpfh = File::Temp->new();
print $tmpfh <<EOT;
record1,textfield1
record2,textfield2
record3,textfield3
record4,textfield4
record5,textfield5
EOT

# `touch $tmpfh`; # uncomment this line to make it work

# get db handle
my $dbh = DBI->connect("DBI:mysql:$dbname:$dbserver", $username, $pwd);

# drop and recreate temp table
$dbh->do("DROP TABLE IF EXISTS $temptable") or die;
$dbh->do("CREATE TABLE $temptable (
`id`       INT(11)      NOT NULL PRIMARY KEY AUTO_INCREMENT,
`header`   VARCHAR(255) NOT NULL,
`sequence` MEDIUMBLOB)")
    or die;

# load data into temp table
my $nrecords = $dbh->do("LOAD DATA LOCAL INFILE '$tmpfh' 
INTO TABLE $temptable 
FIELDS TERMINATED BY ',' 
(header, sequence)")
    or die;

$dbh->disconnect();

printf "Loaded %d records from %s into %s on %s.\n", $nrecords, $tmpfh, $dbname, $dbserver;

1 个答案:

答案 0 :(得分:3)

关闭文件句柄以刷新缓冲区。如果您希望在对象超出范围时保留文件,请保留“UNLINK =&gt; 0”。