$csv.nextRecord
Description
Retourne l'enregistrement suivant lu du CSV donné en référence.
$csv.parse vs $csv.nextRecord
Les méthodes $csv.parse et
$csv.nextRecord permettent toutes les deux de
parcourir un CSV et d'effectuer un traitement pour chaque enregistrement.
Les deux méthodes varient quant à l'approche pour réaliser le
traitement.
Le choix de l'approche appartient donc au développeur, d'autant que les
performances des deux méthodes sont sensiblement identiques.
Syntaxe
$csv.nextRecord( referenceCsv )
Paramètres
referenceCsv pojo
- Référence de CSV obtenue à l'aide de
$csv.load
Retour
Retourne un tableau contenant les valeurs du record, ou null si le parser
a atteint la fin du fichier.
Exemple
L'exemple ci-dessous est un code complet effectuant l'importation des
données "entrées" du registre fédéral des bâtiments et des logements.
L'idée est de parser le CSV en itérant sur les enregistrements (c.-à-d. les
lignes du CSV) et d'envoyer les données dans une table par lots. Pour ce
faire, on construit une requête de la forme:
insert into (col1, col2, ...) values('valA1', 'valB1', ...),('valA2', 'valB2', ...)
Le nombre de lignes enregistrées à la fois est déterminé par la constante
maxCounter. Cette variable joue un grand rôle sur les performances car
elle influe sur le nombre de requêtes envoyées à la base de données. Elle
est fixée à 250 dans l'exemple ci-dessous. Lors des tests, cela a permis
d'importer un peu plus de 15'000 enregistrement à la seconde. Dans les mêmes
conditions, une valeur de 500 permet d'importer environ 18'000
enregistrement par seconde.
La solution proposée ci-dessous n'est toutefois pas optimale. Une importation
par batch serait plus adapté à ce type de traitement.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 | // préparation de la table de destination
$sql.update("create table tmpCsv(EGID varchar(9),
EDID varchar(2),
EGAID varchar(9),
DEINR varchar(12),
ESID varchar(8),
STRNAME varchar(120),
STRNAMK varchar(48),
STRINDX varchar(6),
STRSP varchar(4),
STROFFIZIEL varchar(1),
DPLZ4 varchar(4),
DPLZZ varchar(2),
DPLZNAME varchar(80),
DKODE varchar(11),
DKODN varchar(11),
DOFFADR varchar(1),
DEXPDAT varchar(10))"::T);
$sql.update("delete from tmpCsv"); // note: SQLite ne supporte pas "truncate"
// nombre max de records envoyés en DB à la fois
const maxCounter = 250;
// prototype de requête d'insertion
const sqlProto = "insert into tmpCsv(EGID,EDID,EGAID,DEINR,ESID,STRNAME,STRNAMK,STRINDX,STRSP,STROFFIZIEL,DPLZ4,DPLZZ,DPLZNAME,DKODE,DKODN,DOFFADR,DEXPDAT) values ";
// fonction d'écriture des données en DB
function flushData(data) {
$sql.insert(sqlProto & data);
}
// chargement du CSV
var src = $file.load("C:/Temp/ch/eingang_entree_entrata.csv");
var csv = $csv.load(src, { format: { format: "tdf", skipHeaderRecord: true } });
try {
var nrows = 0;
var counter = maxCounter;
var sqlData = ""; // lot de valeurs à passer à la requête INSERT
var beg = $cal.timestamp(); // juste pour calculer le temps de traitement total
// début des itérations
while (true) {
var row = $csv.nextRecord(csv);
if (row != null) {
// string qui aura la forme ",('valA1','valB1',...)"
var values = "";
for (var col : row) {
values &= ",'${col::Q}'";
}
// on ajoute les valeurs à notre lot de values
sqlData &= ",(" & $string.substring(values, 1) & ")";
// on contrôle s'il y a lieu de faire un flush
if (--counter == 0) {
flushData($string.substring(sqlData, 1)); // on skip la 1re virgule
counter = maxCounter; // reset du compteur
sqlData = ""; // reset du lot de values
}
// comptage de ligne et affichage d'un log tous les 10'000 records
if (++nrows % 10000 == 0) $logger.info(nrows);
}
else {
// fin de fichier
break;
}
}
// on flush le solde de data
if (sqlData != "") {
flushData($string.substring(sqlData, 1));
}
$logger.info("Duration: " & $cal.diff(beg, $cal.timestamp());
}
finally {
// fermeture du parser
$csv.close(csv);
}
|
Voir également l'exemple de la méthode $csv.parse qui réalise
le même traitement, mais de façon différente.