dubbele records bij csv naar db import
Ik heb een script gemaakt om een csv bestand in te lezen naar een mysql database. Na het inlezen moet vervolgens het bestand verplaatst worden. Nou zie ik dat sommige (maar niet alle) records dubbel in de database komen en ik heb geen idee hoe dat kan. Dit is het scipt, hopelijk ziet iemand de fout want ik zie het na uren staren niet meer.
En de csv bestanden zijn gecheckt maar bevatten geen dubbele records en worden goed verplaatst.
Error reporting geeft geen enkele error.
Code (php)
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
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
<?php
error_reporting(E_ALL);
error_reporting(-1);
ini_set('error_reporting', E_ALL);
ini_set('error_log', '/var/www/error.log');
//
$tabelnaam = 'testje';
$dir = '/var/www//data/www/bestandjes/dos';
// database connectie maken
$conn = mysqli_connect('localhost','user','pass','data');
if(!$conn)
{
die(mysqli_error());
}
// verander de cwd omdat dit bestand buiten deze map wordt gerunned
chdir ($dir);
// start invoer
foreach (glob("*.csv") as $bestand)
{
$bestandsnaam = fopen($bestand, 'r');
// als dit woord in een regel staat dan skip deze regel (de kolomkoppen wil je niet inserten en daar staat o.a. dit woord in)
$woord = "disconnect_reason";
$woord2 = "Incoming"; // regels waar dit woord in staat willen we niet hebben
while (!feof($bestandsnaam))
{
$getTextLine = fgets($bestandsnaam);
// de laatste regel in de csv bestanden die aangeleverd worden is leeg dus deze niet meenemen anders krijgen we een lege regel in onze tabel
if(empty($getTextLine))
{
continue;
}
// de eerste regel bevat de headers dus die willen we ook niet meenemen in de database, dat doen we door te filteren op de var $woord
elseif (strpos($getTextLine, $woord) !== false)
{
continue;
}
elseif (strpos($getTextLine, $woord2) !== false)
{
continue;
}
else
{
$explodeLine = explode(",",$getTextLine);
list($id,$h323_conf_id,$account_id,$cli,$cld,$connect_time_utc,$disconnect_time_utc,$disconnect_description,$disconnect_reason,$used_quantity,$bit_flags,$bitflags_description) = $explodeLine;
// zet hier de datums format goed
$connect_time_utc_new = date ('Y-m-d H:i:s', strtotime($connect_time_utc));
$disconnect_time_utc_new = date ('Y-m-d H:i:s', strtotime($disconnect_time_utc));
$qry = "INSERT INTO $tabelnaam (idsod, h323_conf_id, account_id, cli, cld, connect_time_utc, disconnect_time_utc, disconnect_description, disconnect_reason, used_quantity, bit_flags, bitflags_description)
VALUES('".$id."','".$h323_conf_id."','".$account_id."','".$cli."','".$cld."','".$connect_time_utc_new."','".$disconnect_time_utc_new."','".$disconnect_description."','".$disconnect_reason."','".$used_quantity."','".$bit_flags."','".$bitflags_description."')";
mysqli_query($conn,$qry);
}
}
// bestand sluiten
fclose($bestandsnaam);
// bestand verplaatsen
rename($bestand, 'verwerkt/'.$bestand.'');
}
?>
error_reporting(E_ALL);
error_reporting(-1);
ini_set('error_reporting', E_ALL);
ini_set('error_log', '/var/www/error.log');
//
$tabelnaam = 'testje';
$dir = '/var/www//data/www/bestandjes/dos';
// database connectie maken
$conn = mysqli_connect('localhost','user','pass','data');
if(!$conn)
{
die(mysqli_error());
}
// verander de cwd omdat dit bestand buiten deze map wordt gerunned
chdir ($dir);
// start invoer
foreach (glob("*.csv") as $bestand)
{
$bestandsnaam = fopen($bestand, 'r');
// als dit woord in een regel staat dan skip deze regel (de kolomkoppen wil je niet inserten en daar staat o.a. dit woord in)
$woord = "disconnect_reason";
$woord2 = "Incoming"; // regels waar dit woord in staat willen we niet hebben
while (!feof($bestandsnaam))
{
$getTextLine = fgets($bestandsnaam);
// de laatste regel in de csv bestanden die aangeleverd worden is leeg dus deze niet meenemen anders krijgen we een lege regel in onze tabel
if(empty($getTextLine))
{
continue;
}
// de eerste regel bevat de headers dus die willen we ook niet meenemen in de database, dat doen we door te filteren op de var $woord
elseif (strpos($getTextLine, $woord) !== false)
{
continue;
}
elseif (strpos($getTextLine, $woord2) !== false)
{
continue;
}
else
{
$explodeLine = explode(",",$getTextLine);
list($id,$h323_conf_id,$account_id,$cli,$cld,$connect_time_utc,$disconnect_time_utc,$disconnect_description,$disconnect_reason,$used_quantity,$bit_flags,$bitflags_description) = $explodeLine;
// zet hier de datums format goed
$connect_time_utc_new = date ('Y-m-d H:i:s', strtotime($connect_time_utc));
$disconnect_time_utc_new = date ('Y-m-d H:i:s', strtotime($disconnect_time_utc));
$qry = "INSERT INTO $tabelnaam (idsod, h323_conf_id, account_id, cli, cld, connect_time_utc, disconnect_time_utc, disconnect_description, disconnect_reason, used_quantity, bit_flags, bitflags_description)
VALUES('".$id."','".$h323_conf_id."','".$account_id."','".$cli."','".$cld."','".$connect_time_utc_new."','".$disconnect_time_utc_new."','".$disconnect_description."','".$disconnect_reason."','".$used_quantity."','".$bit_flags."','".$bitflags_description."')";
mysqli_query($conn,$qry);
}
}
// bestand sluiten
fclose($bestandsnaam);
// bestand verplaatsen
rename($bestand, 'verwerkt/'.$bestand.'');
}
?>
1. Het record komt al voor
2. Een veld is niet uniek. Vermoedelijk idsod. Vandaar 1.
Je voorkomt dubbele records met INSERT ON DUPLICATE UPDATE
Voorbeeld code
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
INSERT INTO
users ( account, registratiedatum, naam, adres, woonplaats )
VALUES ( faccount, now(), fnaam, fadres, fwoonplaats )
ON DUPLICATE KEY UPDATE
naam = values(naam),
adres = values(adres),
woonplaats = values(woonplaats);
users ( account, registratiedatum, naam, adres, woonplaats )
VALUES ( faccount, now(), fnaam, fadres, fwoonplaats )
ON DUPLICATE KEY UPDATE
naam = values(naam),
adres = values(adres),
woonplaats = values(woonplaats);
waarbij account uniek is.
https://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/
Toevoeging op 27/09/2023 16:54:22:
Even aanvullend.
De code is uit een stored procedure, vandaar de VALUES.
Code (php)
1
CREATE PROCEDURE `spUserInsert`(IN `faccount` char(15), IN `fnaam` char(50), IN `fadres` char(50), IN `fwoonplaats` char(50))
Gewijzigd op 27/09/2023 16:41:36 door Adoptive Solution
$explodeLine = explode(",",$getTextLine);
je weet dus 100% zeker dat je velden geen komma's van zichzelf bevatten?
Gebruik anders de csv functies van PHP.
https://www.php.net/manual/en/function.str-getcsv.php
2)
Mysql kent ook zelf de mogelijkheid om CSV files in te lezen, wat een heel stuk sneller is dan via losse query's in php.
"read data infile ... "
Hallo allemaal, Ik denk dat de oplossing van een goede manier is om dit probleem op te lossen. Door een unieke ID toe te voegen aan elk record, kunt u dubbele records detecteren en verwijderen. Ik ben gewoon aan het leren. Hoewel al een half jaar. Het is goed voor mij om onder jullie te zijn.