1 votes

csv import mysql null

Je dois importer des données au format csv dans une base de données mysql (mariadb). Il n'y a pas d'en-tête csv et les lignes ressemblent à ceci :

00323acd-7909-41a4-a849-073ca3391dcf,2014-05, \N
00323acd-7909-41a4-a849-073ca3391dcf,2014-05,1

Ils contiennent donc un identifiant hexagonal, une combinaison année/mois et une valeur int optionnelle. J'utilise l'élément \N (hex : 5c 4e) pour marquer les valeurs NULL (mysql utilise également ce style pour exporter les valeurs nulles).

LOAD DATA LOCAL INFILE 'path/to/data.csv' INTO TABLE data_table 
FIELDS TERMINATED BY ',' ENCLOSED BY '' 
LINES  TERMINATED BY '\n' (id, @date_time_variable, value) 
SET date = STR_TO_DATE(@date_time_variable, '%Y-%m');

Mais il semble que la base de données ne reconnaisse pas l'élément ' \N Valeurs nulles codées "Null".

Query OK, 38581 rows affected, 14596 warnings (0.54 sec)
Records: 38581  Deleted: 0  Skipped: 0  Warnings: 14596

MariaDB [run5]> show warnings;
+---------+------+-------------------------------------------------------------+
| Level   | Code | Message                                                     |
+---------+------+-------------------------------------------------------------+
' for column 'value' at row 1   |ger value: 'N
' for column 'value' at row 2   |ger value: 'N
' for column 'value' at row 3   |ger value: 'N

Le schéma se présente comme suit :

CREATE TABLE `data_table` (
  `id` char(36) NOT NULL,
  `date` date NOT NULL,
  `value` int(11) DEFAULT NULL,
  KEY `mbid` (`id`),
  KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Quelqu'un connaît-il cette erreur ou une solution ?

EDIT :

voici le résultat de show warnings \G; :

MariaDB [run5]> show warnings \G;
*************************** 1. row ***************************
  Level: Warning
   Code: 1366
' for column 'value' at row 1lue: 'N
*************************** 2. row ***************************
  Level: Warning
   Code: 1366
' for column 'value' at row 2lue: 'N
*************************** 3. row ***************************
  Level: Warning
   Code: 1366
' for column 'value' at row 3lue: 'N
*************************** 4. row ***************************
  Level: Warning
   Code: 1366
' for column 'value' at row 4lue: 'N
*************************** 5. row ***************************
  Level: Warning
   Code: 1366
' for column 'value' at row 5lue: 'N
...

Et voici un extrait hexadécimal du fichier :

~/D/path  head -n 2 data/file.csv | hexdump -C                                           master  
00000000  30 30 33 32 33 63 63 64  2d 37 39 30 39 2d 34 31  |00323ccd-7909-41|
00000010  61 34 2d 61 38 34 39 2d  30 37 33 63 61 33 33 39  |a4-a849-073ca339|
00000020  31 64 63 66 2c 32 30 31  34 2d 30 35 2c 5c 4e 0d  |1dcf,2014-05,\N.|
00000030  0a 30 30 33 32 33 63 63  64 2d 37 39 30 39 2d 34  |.00323ccd-7909-4|
00000040  31 61 34 2d 61 38 34 39  2d 30 37 33 63 61 33 33  |1a4-a849-073ca33|
00000050  39 31 64 63 66 2c 32 30  31 34 2d 31 32 2c 5c 4e  |91dcf,2014-12,\N|
00000060  0d 0a                                             |..|
00000062

La troisième ligne contient 2c 5c 4e qui signifie ,\N et c'est correct, ou non ?

EDIT 2 :

J'ai mis à jour la requête car j'ai utilisé le mauvais terminateur de ligne ( \n au lieu de \r\n ). Je reçois maintenant un seul message d'erreur concernant cette valeur erronée :

MariaDB [run5]> LOAD DATA LOCAL INFILE '/path/data.csv' INTO TABLE data_table FIELDS TERMINATED BY ',' ENCLOSED BY '' LINES  TERMINATED BY '\n\r' (id, @date_time_variable, value) SET date = STR_TO_DATE(@date_time_variable, '%Y-%m');
Query OK, 1 row affected, 1 warning (0.01 sec)       
Records: 1  Deleted: 0  Skipped: 0  Warnings: 1

MariaDB [run5]> show warnings \G
*************************** 1. row ***************************
  Level: Warning
   Code: 1366
Message: Incorrect integer value: 'N
00323ccd-7909-41a4-a849-073ca3391dcf' for column 'value' at row 1
1 row in set (0.00 sec)

3voto

Jules Points 240

Je n'ai pas essayé, mais d'après ma lecture du manuel de LOAD DATA INFILE, l'interprétation de " \N "Le traitement des séquences d'échappement est contrôlé par la clause ESCAPED BY, et la valeur par défaut est de ne pas effectuer le traitement des séquences d'échappement. Si c'est le cas, l'ajout de la clause "ESCAPED BY ' \\ '" à votre requête devrait vous permettre d'obtenir les résultats souhaités.

1voto

freddie montana Points 21

Je soupçonne que les données importées sont mal formées. Plus précisément \N manque \ dans certains ou dans tous les cas.

Vérifier que les données sont correctes. Vous pouvez procéder de la manière suivante :

$ awk -F, '$3=="\\N"{print $0}' moo.csv
00323acd-7909-41a4-a849-073ca3391dcf,2014-05,\N

$ awk -F, '$3=="N"{print $0}' moo.csv
00323acd-7909-41a4-a849-073ca3391dcf,2014-05,N

De plus, la sortie d'avertissement est coupée. Réessayez l'importation, puis utilisez ce qui suit :

show warnings \G

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X