Importar CSV a la tabla mysql

96

¿Cuál es la forma mejor / más rápida de cargar un archivo csv en una tabla mysql? Me gustaría que la primera fila de datos se usara como nombres de columna.

Encontró esto:

Cómo importar un archivo CSV a una tabla MySQL

¿Pero la única respuesta fue usar una GUI y no un shell?

mcm
fuente
3
E incluso la solución GUI no toma los nombres de las columnas del csv ... debe crear la tabla completa antes de importar-
Dominique
La pregunta ya tiene una respuesta aquí stackoverflow.com/questions/3635166/…
David
la respuesta aceptada en la pregunta a la que está enlazando estaba usando una GUI. La respuesta a sus referencias se proporcionó ayer, mientras que esta pregunta (respuesta) es de 2012.
mcm

Respuestas:

147

En lugar de escribir un script para extraer información de un archivo CSV, puede vincular MYSQL directamente a él y cargar la información utilizando la siguiente sintaxis SQL.

Para importar un archivo de Excel a MySQL, primero expórtelo como archivo CSV. Elimine los encabezados CSV del archivo CSV generado junto con los datos vacíos que Excel puede haber puesto al final del archivo CSV.

Luego puede importarlo a una tabla MySQL ejecutando:

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

como sigue leyendo: Importar archivo CSV directamente en MySQL

EDITAR

Para su caso, primero deberá escribir un intérprete, para encontrar la primera fila y asignarlos como nombres de columna.


EDITAR-2

De los documentos de MySQL sobre LOAD DATAsintaxis :

La IGNORE number LINESopción se puede utilizar para ignorar las líneas al principio del archivo. Por ejemplo, puede usar IGNORE 1 LINESpara omitir una línea de encabezado inicial que contenga nombres de columna:

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

Por lo tanto, puede utilizar la siguiente declaración:

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
fuente
8
En lugar de eliminar la primera línea, puede agregar IGNORE 1 LINESa la consulta
mb14
¿Sabe si hay una manera de establecer la ruta del archivo al archivo csv?
JasonDavis
¿Cómo depurar este comando cuando falla? Estoy tratando de cargar un archivo con este comando pero no hace nada.
¿qué tal si me gustaría ignorar una columna en csv?
Marci-man
cómo otorgar permiso para que el servidor mysql acceda a mi archivo local csv que se ejecuta en aws (rds)
rahul
24

Aquí hay un script de línea de comando PHP simple que hará lo que necesita:

<?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);

?>

Creará una tabla basada en la primera fila e importará las filas restantes en ella. Aquí está la sintaxis de la línea de comandos:

php csv_import.php csv_file.csv table_name
Hawkee
fuente
2
Guión impresionante. Para aquellos con archivos CSV entre comillas dobles (lea la mayoría de la gente) agregue `ENCASED IN '\"' `a fields terminated by ','... incluso funciona con CSV parcialmente entrecomillados.
Joel Mellon
3
Creo que te refieres a ENCLOSED BY '\"'... también, mucha gente necesitará LINES TERMINATED BY '\r\n'si usa un CSV de Windows. Y finalmente, es prudente escapar de los nombres de campo con $columns .= "`$column` varchar(250)";
comillas invertidas
1
Esta respuesta es mucho mejor que la respuesta aceptada. En particular, permite lo que pidió el OP, y también quiero: "la primera fila de datos se use como nombres de columna". (Preferiría un script en Python, por lo que no tengo que instalar PHP, pero no debería ser difícil
portarlo
2
@YumYumYum ¿Puedes dar más detalles sobre el problema que tienes?
Hawkee
¿Puedo invitarte una cerveza?
Joe
4

Si tiene la capacidad de instalar phpadmin, hay una sección de importación donde puede importar archivos csv a su base de datos, incluso hay una casilla de verificación para establecer el encabezado en la primera línea del archivo que contiene los nombres de las columnas de la tabla (si está desmarcado, el la primera línea pasará a formar parte de los datos

Jose Ortiz
fuente
Estoy realmente sorprendido de que tenga que usar un complemento como phpadmin para obtener esta funcionalidad, gracias por su respuesta
chrisfs
Esto acaba de alegrarme el día
Marcos
4

Primero cree una tabla en la base de datos con el mismo número de columnas que el archivo csv.

Luego usa la siguiente consulta

LOAD DATA INFILE 'D:/Projects/testImport.csv' INTO TABLE cardinfo
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
Mukesh
fuente
¿qué tal si me gustaría ignorar una columna en csv?
Marci-man
3

Para cargar datos desde un archivo de texto o un archivo csv, el comando es

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

En el comando anterior, en mi caso, solo hay una columna para cargar, por lo que no hay "terminado por" ni "encerrado por", así que lo mantuve vacío; de lo contrario, el programador puede ingresar el carácter de separación. por ej. , (coma) o "o; o cualquier cosa.

** para personas que usan mysql versión 5 y superior **

Antes de cargar el archivo en mysql debe asegurarse de que la línea de remolque debajo se agregue en el costado etc/mysql/my.cnf

para editar el comando my.cnf es

sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  
Rakesh
fuente
3

Si inicia mysql como "mysql -u -p --local-infile", funcionará bien

marciomolusco
fuente
2

Escribí un código para hacer esto, pondré algunos fragmentos:

$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

Luego, obtenga los encabezados CSV para que pueda decirle a mysql cómo importar (nota: asegúrese de que sus columnas de mysql coincidan exactamente con las columnas de csv):

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

Luego envíe su consulta al servidor 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
fuente
1

Luché con esto durante algún tiempo. El problema no radica en cómo cargar los datos, sino en cómo construir la tabla para contenerlos. Debe generar una declaración DDL para crear la tabla antes de importar los datos.

Particularmente difícil si la tabla tiene una gran cantidad de columnas.

Aquí hay un script de Python que (casi) hace el trabajo:

#!/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'

El problema que queda por resolver es que el nombre del campo final y la declaración del tipo de datos terminan con una coma, y ​​el analizador mySQL no lo tolerará.

Por supuesto, también tiene el problema de que utiliza el tipo de datos TEXT para cada campo. Si la tabla tiene varios cientos de columnas, VARCHAR (64) hará que la tabla sea demasiado grande.

Esto también parece romperse en el recuento máximo de columnas para mySQL. Ahí es cuando es el momento de pasar a Hive o HBase si puede.

agentv
fuente
1

Así es como lo hice en Python usando csv y 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()

Puntos clave

  • Utilice declaraciones preparadas para INSERT
  • Abra el archivo.csv en 'rb'binario
  • Algunos archivos CSV pueden necesitar ajustes , como la skipinitialspaceopción.
  • Si 255no es lo suficientemente ancho, obtendrá errores en INSERT y tendrá que empezar de nuevo.
  • Ajustar los tipos de columna, p. Ej. ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • Agregue una clave principal , p. Ej.ALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;
Bob Stein
fuente
0

Importar archivos CSV a la tabla 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

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

Elangovan
fuente
0

Como han mencionado otros, el archivo local de datos de carga funciona bien. Probé el script php que publicó Hawkee, pero no funcionó para mí. En lugar de depurarlo, esto es lo que hice:

1) copie / pegue la fila del encabezado del archivo CSV en un archivo txt y edítelo con emacs. agregue una coma y CR entre cada campo para colocar cada uno en su propia línea.
2) Guarde ese archivo como FieldList.txt
3) edite el archivo para incluir defns para cada campo (la mayoría eran varchar, pero bastantes eran int (x). Agregue crear tabla nombre de tabla (al principio del archivo y) al final del archivo. Guárdelo como CreateTable.sql
4) inicie el cliente mysql con la entrada del archivo Createtable.sql para crear la tabla
5) inicie el cliente mysql, copie / pegue en la mayor parte del comando 'LOAD DATA INFILE' sustituyendo mi tabla nombre y nombre del archivo csv. Pegue en el archivo FieldList.txt. Asegúrese de incluir 'IGNORAR 1 LÍNEAS' antes de pegar en la lista de campos

Parece mucho trabajo, pero fácil con emacs .....

Jim Sims
fuente
0

Use la aplicación TablePlus: haga clic con el botón derecho en el nombre de la tabla en el panel derecho. Elija Importar ...> Desde CSV. Elija el archivo CSV. Revise la columna correspondiente y presione Importar. Todo listo.

Milad Hatami
fuente
-3

Tengo una búsqueda en Google de muchas formas de importar csv a mysql, incluir "cargar datos de archivo", usar mysql workbench, etc.

cuando uso el botón de importación de mysql workbench, primero debe crear la tabla vacía por su cuenta, configurar cada tipo de columna por su cuenta. Nota: debe agregar la columna de ID al final como clave principal y no nula y auto_increment, de lo contrario, el botón de importación no estará visible más adelante. Sin embargo, cuando comienzo a cargar el archivo CSV, no se carga nada, parece un error. Me rindo.

Por suerte, la mejor manera fácil que encontré hasta ahora es usar mysql de Oracle para Excel. puedes descargarlo desde aquí mysql para excel

Esto es lo que va a hacer: abra el archivo csv en excel, en la pestaña Datos, busque el botón mysql para excel

seleccione todos los datos, haga clic en exportar a mysql. Nota para establecer una columna de ID como clave principal.

cuando termine, vaya a mysql workbench para modificar la tabla, por ejemplo, el tipo de moneda debe ser decimal (19,4) para una gran cantidad decimal (10,2) para uso regular. otro tipo de campo se puede establecer en varchar (255).

hoogw
fuente