web-dev-qa-db-fra.com

Importer CSV dans la table mysql

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

Trouvé ceci:

Comment importer un fichier CSV dans une table MySQL

Mais la seule solution consistait à utiliser une interface graphique et non un shell?

94
lcm

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

Pour importer un fichier Excel dans MySQL, exportez-le d'abord en tant que 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 lançant:

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

comme lu sur: Importer un fichier CSV directement dans MySQL

MODIFIER

Dans votre cas, vous devez d’abord écrire un interprète pour trouver la première ligne et les attribuer en tant que noms de colonnes.


EDIT-2

Depuis la documentation MySQL sur la syntaxe LOAD DATA) :

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

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)
147
hjpotter92

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
23
Hawkee

Commencez par créer une table dans la base de données avec le même nombre de colonnes que dans le fichier csv.

Puis 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'
4
Mukesh

si vous avez la possibilité d'installer phpadmin, il existe une section d'importation où vous pouvez importer des fichiers csv dans votre base de données. Il existe même une case à cocher pour définir l'en-tête sur la première ligne du fichier contenant les noms des colonnes la première ligne fera partie des données

4
Jose Ortiz

Pour charger des données à partir d'un fichier texte ou 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, il n'y a donc pas de "terminés par" et "enfermés par", donc je l'ai laissée vide, sinon le programmeur peut entrer le caractère de séparation. pour par exemple. , (virgule) ou "ou; ou toute autre chose.

** pour les personnes utilisant mysql version 5 ou supérieure **

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

modifier la commande my.cnf est

Sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  
3
Rakesh

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

3
marciomolusco

J'ai écrit du code pour le faire, je vais ajouter 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 pour que vous sachiez comment importer (remarque: assurez-vous que vos colonnes mysql correspondent exactement à celles de 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());
2
ravenchilde

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

Particulièrement difficile si la table a un grand nombre de colonnes.

Voici un script python qui fait (presque) tout 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 que l'analyseur MySQL ne le tolérera pas.

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

Cela semble également se rompre au nombre maximal de colonnes pour MySQL. C'est le moment de passer à Hive ou HBase si vous en êtes capable.

2
agentv

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

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 l'INSERT
  • Ouvrez le fichier.csv dans 'rb' binary
  • Certains fichiers CSV peuvent nécessiter peaufiner , comme l'option skipinitialspace.
  • Si 255 n'est pas assez large, vous obtiendrez des erreurs sur INSERT et vous devrez recommencer.
  • Ajustez les types de colonne, par exemple. ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • Ajoutez un clé primaire , par ex. ALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;
1
Bob Stein

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

0
Elangovan

Comme d'autres l'ont mentionné, l'infile local de données de charge fonctionne parfaitement. J'ai essayé le script php que Hawkee a posté, mais cela n'a pas fonctionné pour moi. Plutôt que de le déboguer, voici ce que j'ai fait:

1) copier/coller la ligne d’en-tête du fichier CSV dans un fichier txt et le modifier avec emacs. ajoutez une virgule et un CR entre chaque champ pour que chacun d'eux apparaisse sur sa propre ligne.
2) Enregistrez ce fichier en tant que FieldList.txt
3) éditez le fichier pour inclure des définitions pour chaque champ (la plupart étaient varchar, mais quelques-uns étaient int (x). Ajoutez create table nomtable (au début du fichier et ) à la 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émarrer le client mysql, copier/coller dans la plupart des commandes 'LOAD DATA INFILE' remplaçant mon nom de table et mon nom de fichier csv. Collez dans le fichier FieldList.txt. Assurez-vous d'inclure les "lignes IGNORE 1" avant de coller dans la liste de champs

Cela ressemble à beaucoup de travail, mais facile avec emacs .....

0
jim sims