2 votes

DBI::mysql et File::Temp

Je tente de charger des données dans une base de données MySQL en utilisant l'instruction LOAD DATA LOCAL INFILE. Sur des fichiers normaux, cela fonctionne bien.

Si je crée un fichier temporaire avec File::Temp, stocke des données CSV dedans, ferme le fichier et les charge directement dans la base de données en utilisant

$dbh->do("LOAD DATA LOCAL INFILE '$tempfile' INTO TABLE $temptable FIELDS TERMINATED BY ',');

les deux derniers enregistrements sont systématiquement omis. Cependant, si j'effectue une action avec le fichier temporaire entre sa création et son chargement, par exemple avec

`touch $tempfile`;

tout fonctionne comme prévu.

Est-ce un problème avec le pilote MySQL ayant des difficultés avec les fichiers temporaires fraîchement créés ? Est-ce un problème de système de fichiers (ext4), peut-être un problème de vidage de cache qui ne se produit pas assez rapidement ? Est-ce que j'oublie quelque chose ici ?

ÉDIT : En fait, tous les enregistrements sont omis si le fichier CSV temporaire n'est pas créé par une sous-routine de conversion de format, mais à la main comme montré ci-dessous. J'ai également inclus le code pour l'interaction avec la base de données. Notez le touch $tmpfh en commentaire, qui, s'il est décommenté, ferait fonctionner l'exemple.

Ajouter UNLINK => 0 à File::Temp->new() ne change rien.

my $tmpfh = File::Temp->new();
print $tmpfh <connect("DBI:mysql:$dbname:$dbserver", $username, $pwd);

# supprimer et recréer la table temporaire
$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;

# charger les données dans la table temporaire
my $nrecords = $dbh->do("LOAD DATA LOCAL INFILE '$tmpfh' 
INTO TABLE $temptable 
FIELDS TERMINATED BY ',' 
(header, sequence)")
    or die;

$dbh->disconnect();

printf "Chargé %d enregistrements de %s dans %s sur %s.\n", $nrecords, $tmpfh, $dbname, $dbserver;

3voto

runrig Points 5422

Fermez la poignée de fichier pour vider le tampon. Gardez le "UNLINK => 0" si vous voulez que le fichier reste lorsque l'objet sort de portée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X