Importer le CSV dans la table mysql

96

Quel est le moyen le meilleur / le plus rapide pour télécharger un fichier csv dans une table mysql? Je voudrais que la première ligne de données soit utilisée comme noms de colonne.

Trouvé ceci:

Comment importer un fichier CSV dans une table MySQL

Mais la seule réponse était d'utiliser une interface graphique et non un shell?

lcm
la source
3
Et même la solution GUI ne prend pas les noms de colonnes du csv ... vous devez créer la table entière avant l'importation-
Dominique
La question a déjà une réponse ici stackoverflow.com/questions/3635166/…
David
la réponse acceptée à la question à laquelle vous créez un lien utilisait une interface graphique. La réponse que vous êtes des références a été fournie hier alors que cette question (réponse) date de 2012.
lcm

Réponses:

147

Au lieu d'écrire un script pour extraire des informations d'un fichier CSV, vous pouvez lier directement MYSQL à celui-ci et télécharger les informations à l'aide de la syntaxe SQL suivante.

Pour importer un fichier Excel dans MySQL, exportez-le d'abord sous forme de fichier CSV. Supprimez les en-têtes CSV du fichier CSV généré ainsi que les données vides qu'Excel peut avoir placées à la fin du fichier CSV.

Vous pouvez ensuite l'importer dans une table MySQL en exécutant:

load data local infile 'uniq.csv' into table tblUniq fields terminated by ','
  enclosed by '"'
  lines terminated by '\n'
    (uniqName, uniqCity, uniqComments)

comme lisez la suite: Importez le fichier CSV directement dans MySQL

ÉDITER

Pour votre cas, vous devrez d'abord écrire un interpréteur, pour trouver la première ligne et les affecter comme noms de colonne.


EDIT-2

À partir de la documentation MySQL sur la LOAD DATAsyntaxe :

L' IGNORE number LINESoption peut être utilisée pour ignorer les lignes au début du fichier. Par exemple, vous pouvez utiliser IGNORE 1 LINESpour ignorer une ligne d'en-tête initiale contenant les noms de colonnes:

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;

Par conséquent, vous pouvez utiliser l'instruction suivante:

LOAD DATA LOCAL INFILE 'uniq.csv'
INTO TABLE tblUniq
FIELDS TERMINATED BY ','
    ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(uniqName, uniqCity, uniqComments)
hjpotter92
la source
8
Au lieu de supprimer la première ligne, vous pouvez ajouter IGNORE 1 LINESà la requête
mb14
Savez-vous s'il existe un moyen de définir le chemin du fichier vers le fichier csv?
JasonDavis
Comment déboguer cette commande en cas d'échec? J'essaye de charger un fichier avec cette commande mais ça ne fait rien.
que diriez-vous si je voudrais ignorer une colonne dans csv?
Marci-man
comment autoriser l'accès à mon fichier local csv par le serveur mysql fonctionnant sur aws (rds)
rahul
24

Voici un simple script de ligne de commande PHP qui fera ce dont vous avez besoin:

<?php

$host = 'localhost';
$user = 'root';
$pass = '';
$database = 'database';

$db = mysql_connect($host, $user, $pass);
mysql_query("use $database", $db);

/********************************************************************************/
// Parameters: filename.csv table_name

$argv = $_SERVER[argv];

if($argv[1]) { $file = $argv[1]; }
else {
    echo "Please provide a file name\n"; exit; 
}
if($argv[2]) { $table = $argv[2]; }
else {
    $table = pathinfo($file);
    $table = $table['filename'];
}

/********************************************************************************/
// Get the first row to create the column headings

$fp = fopen($file, 'r');
$frow = fgetcsv($fp);

foreach($frow as $column) {
    if($columns) $columns .= ', ';
    $columns .= "`$column` varchar(250)";
}

$create = "create table if not exists $table ($columns);";
mysql_query($create, $db);

/********************************************************************************/
// Import the data into the newly created table.

$file = $_SERVER['PWD'].'/'.$file;
$q = "load data infile '$file' into table $table fields terminated by ',' ignore 1 lines";
mysql_query($q, $db);

?>

Il créera une table basée sur la première ligne et y importera les lignes restantes. Voici la syntaxe de la ligne de commande:

php csv_import.php csv_file.csv table_name
Hawkee
la source
2
Script génial. Pour ceux qui ont des fichiers CSV entre guillemets (lire la plupart des gens), ajoutez `ENCASED IN '\"' `à fields terminated by ','... cela fonctionne même avec des CSV partiellement double guillemets.
Joel Mellon
3
Je pense que vous voulez dire ENCLOSED BY '\"'... aussi, beaucoup de gens auront besoin LINES TERMINATED BY '\r\n'si vous utilisez un CSV de Windows. Et enfin, il est judicieux d'échapper aux noms de champs avec des backticks au cas où il y aurait des espaces:$columns .= "`$column` varchar(250)";
dlo
1
Cette réponse est bien meilleure que la réponse acceptée. En particulier, il permet ce que l'OP a demandé, et je veux aussi: "la première ligne de données soit utilisée comme nom de colonne". (Je préférerais un script en Python, donc je n'ai pas besoin d'installer PHP, mais il ne devrait pas être difficile de le porter.)
LarsH
2
@YumYumYum Pouvez-vous nous en dire plus sur le problème que vous rencontrez?
Hawkee
Puis-je vous acheter une bière?
Joe
4

si vous avez la possibilité d'installer phpadmin, il y a une section d'importation où vous pouvez importer des fichiers csv dans votre base de données, il y a même une case à cocher pour définir l'en-tête sur la première ligne du fichier contient les noms des colonnes de la table (si cela n'est pas coché, le la première ligne fera partie des données

José Ortiz
la source
Je suis vraiment surpris que vous deviez utiliser un add-on comme phpadmin pour obtenir cette fonctionnalité, merci pour votre réponse
chrisfs
Cela vient de faire ma journée
Mark
4

Créez d'abord une table dans la base de données avec le même nombre de colonnes que dans le fichier csv.

Ensuite, utilisez la requête suivante

LOAD DATA INFILE 'D:/Projects/testImport.csv' INTO TABLE cardinfo
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
Mukesh
la source
que diriez-vous si je voudrais ignorer une colonne dans csv?
Marci-man
3

Pour charger des données à partir d'un fichier texte ou d'un fichier csv, la commande est

load data local infile 'file-name.csv'
into table table-name
fields terminated by '' enclosed by '' lines terminated by '\n' (column-name);

Dans la commande ci-dessus, dans mon cas, il n'y a qu'une seule colonne à charger, donc il n'y a pas de "terminé par" et "entouré par" donc je l'ai gardé vide sinon le programmeur peut entrer le caractère de séparation. par exemple. , (virgule) ou "ou; ou quoi que ce soit.

** pour les personnes qui utilisent mysql version 5 et supérieure **

Avant de charger le fichier dans mysql, assurez-vous que la ligne de remorquage ci-dessous est ajoutée à côté etc/mysql/my.cnf

pour modifier la commande my.cnf est

sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  
Rakesh
la source
3

Si vous démarrez mysql en tant que "mysql -u -p --local-infile", cela fonctionnera correctement

marciomolusco
la source
2

J'ai écrit du code pour ce faire, je vais mettre quelques extraits:

$dir = getcwd(); // Get current working directory where this .php script lives
$fileList = scandir($dir); // scan the directory where this .php lives and make array of file names

Ensuite, récupérez les en-têtes CSV afin de pouvoir dire à mysql comment importer (note: assurez-vous que vos colonnes mysql correspondent exactement aux colonnes csv):

//extract headers from .csv for use in import command
$headers = str_replace("\"", "`", array_shift(file($path)));
$headers = str_replace("\n", "", $headers);

Envoyez ensuite votre requête au serveur mysql:

mysqli_query($cons, '
        LOAD DATA LOCAL INFILE "'.$path.'"
            INTO TABLE '.$dbTable.'  
            FIELDS TERMINATED by \',\' ENCLOSED BY \'"\'
            LINES TERMINATED BY \'\n\'
            IGNORE 1 LINES
            ('.$headers.')
            ;
        ')or die(mysql_error());
Ravenchilde
la source
1

J'ai lutté avec ça pendant un certain temps. Le problème ne réside pas dans la façon de charger les données, mais dans la façon de construire la table pour les contenir. Vous devez générer une instruction DDL pour créer la table avant d'importer les données.

Particulièrement difficile si le tableau comporte un grand nombre de colonnes.

Voici un script python qui fait (presque) le travail:

#!/usr/bin/python    
import sys
import csv

# get file name (and hence table name) from command line
# exit with usage if no suitable argument   
if len(sys.argv) < 2:
   sys.exit('Usage: ' + sys.argv[0] + ': input CSV filename')
ifile = sys.argv[1]

# emit the standard invocation
print 'create table ' + ifile + ' ('

with open(ifile + '.csv') as inputfile:
   reader = csv.DictReader(inputfile)
   for row in reader:
      k = row.keys()
      for item in k:
         print '`' + item + '` TEXT,'
      break
   print ')\n'

Le problème qu'il reste à résoudre est que le nom de champ final et la déclaration du type de données se terminent par une virgule, et l'analyseur mySQL ne le tolérera pas.

Bien sûr, il a également le problème qu'il utilise le type de données TEXT pour chaque champ. Si la table a plusieurs centaines de colonnes, alors VARCHAR (64) rendra la table trop grande.

Cela semble également casser au nombre maximum de colonnes pour mySQL. C'est à ce moment qu'il est temps de passer à Hive ou HBase si vous le pouvez.

agentv
la source
1

Voici comment je l'ai fait en Python en utilisant csv et le connecteur MySQL :

import csv
import mysql.connector

credentials = dict(user='...', password='...', database='...', host='...')
connection = mysql.connector.connect(**credentials)
cursor = connection.cursor(prepared=True)
stream = open('filename.csv', 'rb')
csv_file = csv.DictReader(stream, skipinitialspace=True)

query = 'CREATE TABLE t ('
query += ','.join('`{}` VARCHAR(255)'.format(column) for column in csv_file.fieldnames)
query += ')'
cursor.execute(query)
for row in csv_file:
    query = 'INSERT INTO t SET '
    query += ','.join('`{}` = ?'.format(column) for column in row.keys())
    cursor.execute(query, row.values())

stream.close()
cursor.close()
connection.close()

Points clés

  • Utiliser des instructions préparées pour INSERT
  • Ouvrez le fichier.csv en 'rb'binaire
  • Certains fichiers CSV peuvent nécessiter des ajustements , tels que l' skipinitialspaceoption.
  • Si ce 255n'est pas assez large, vous obtiendrez des erreurs sur INSERT et devrez recommencer.
  • Ajustez les types de colonnes, par exemple ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • Ajouter une clé primaire , par exempleALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;
Bob Stein
la source
0

Importer des fichiers CSV dans la table mysql

LOAD DATA LOCAL INFILE 'd:\\Site.csv' INTO TABLE `siteurl` FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\r\n';

Character   Escape Sequence
\0      An ASCII NUL (0x00) character
\b      A backspace character
\n      A newline (linefeed) character
\r      A carriage return character
\t      A tab character.
\Z      ASCII 26 (Control+Z)
\N      NULL

visites: http://www.webslessons.com/2014/02/import-csv-files-using-php-and-mysql.html

Elangovan
la source
0

Comme d'autres l'ont mentionné, le fichier local des données de chargement fonctionne très bien. J'ai essayé le script php publié par Hawkee, mais cela n'a pas fonctionné pour moi. Plutôt que de le déboguer, voici ce que j'ai fait:

1) copiez / collez la ligne d'en-tête du fichier CSV dans un fichier txt et éditez avec emacs. ajoutez une virgule et un CR entre chaque champ pour obtenir chacun sur sa propre ligne.
2) Enregistrez ce fichier sous FieldList.txt
3) modifiez le fichier pour inclure defns pour chaque champ (la plupart étaient varchar, mais un certain nombre étaient int (x). Ajoutez create table tablename (au début du fichier et) au fin du fichier. Enregistrez-le sous CreateTable.sql
4) démarrez le client mysql avec l'entrée du fichier Createtable.sql pour créer la table
5) démarrez le client mysql, copiez / collez dans la plupart de la commande 'LOAD DATA INFILE' remplaçant ma table nom et nom de fichier csv. Collez le fichier FieldList.txt. Assurez-vous d'inclure les 'IGNORER 1 LIGNES' avant de coller dans la liste des champs

Cela semble beaucoup de travail, mais facile avec emacs .....

Jim Sims
la source
0

Utilisez l'application TablePlus: Cliquez avec le bouton droit sur le nom de la table dans le panneau de droite Choisissez Importer ...> À partir de CSV Choisissez un fichier CSV Vérifiez la correspondance des colonnes et appuyez sur Tout importer!

Milad Hatami
la source
-3

J'ai une recherche sur Google de nombreuses façons d'importer csv dans mysql, d'inclure "load data infile", d'utiliser mysql workbench, etc.

lorsque j'utilise le bouton d'importation de mysql workbench, vous devez d'abord créer vous-même la table vide, définir chaque type de colonne vous-même. Remarque: vous devez ajouter la colonne ID à la fin en tant que clé primaire et non null et auto_increment, sinon, le bouton d'importation ne sera pas visible plus tard. Cependant, lorsque je commence à charger le fichier CSV, rien n'est chargé, cela semble être un bogue. J'abandonne.

Heureusement, le meilleur moyen simple que j'ai trouvé jusqu'à présent est d'utiliser le mysql d'Oracle pour Excel. vous pouvez le télécharger ici mysql pour excel

Voici ce que vous allez faire: ouvrez le fichier csv dans Excel, dans l'onglet Données, trouvez mysql pour le bouton Excel

sélectionnez toutes les données, cliquez sur exporter vers mysql. Remarque pour définir une colonne ID comme clé primaire.

une fois terminé, accédez à mysql workbench pour modifier la table, par exemple, le type de devise doit être décimal (19,4) pour un grand nombre décimal (10,2) pour une utilisation régulière. un autre type de champ peut être défini sur varchar (255).

hoogw
la source