Importar CSV para tabela mysql

96

Qual é a maneira melhor / mais rápida de fazer upload de um arquivo csv em uma tabela mysql? Eu gostaria que a primeira linha de dados fosse usada como os nomes das colunas.

Encontrei isto:

Como importar arquivo CSV para a tabela MySQL

Mas a única resposta era usar uma GUI e não shell?

lcm
fonte
3
E mesmo a solução GUI não pega os nomes das colunas do csv ... você precisa criar a tabela inteira antes de importar-
Dominique
A pergunta já tem uma resposta aqui stackoverflow.com/questions/3635166/…
David
a resposta aceita para a pergunta para a qual você está criando um link estava usando uma GUI. A resposta às suas referências foi fornecida ontem, enquanto esta pergunta (resposta) é de 2012.
lcm

Respostas:

147

Em vez de escrever um script para obter informações de um arquivo CSV, você pode vincular MYSQL diretamente a ele e fazer upload das informações usando a seguinte sintaxe SQL.

Para importar um arquivo Excel para o MySQL, primeiro exporte-o como um arquivo CSV. Remova os cabeçalhos CSV do arquivo CSV gerado junto com os dados vazios que o Excel pode ter colocado no final do arquivo CSV.

Você pode então importá-lo para uma tabela MySQL executando:

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

conforme lido em: Importar arquivo CSV diretamente para o MySQL

EDITAR

Para o seu caso, você precisará escrever um interpretador primeiro, para localizar a primeira linha e atribuí-los como nomes de coluna.


EDIT-2

Da documentação do MySQL sobre LOAD DATAsintaxe :

A IGNORE number LINESopção pode ser usada para ignorar as linhas no início do arquivo. Por exemplo, você pode usar IGNORE 1 LINESpara pular uma linha de cabeçalho inicial contendo nomes de coluna:

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

Portanto, você pode usar a seguinte declaração:

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
fonte
8
Em vez de remover a primeira linha, você pode adicionar IGNORE 1 LINESà consulta
mb14
Você sabe se existe uma maneira de definir o caminho do arquivo para o arquivo csv?
JasonDavis
Como depurar este comando quando está falhando? Estou tentando carregar um arquivo com este comando, mas não está fazendo nada.
que tal se eu gostaria de ignorar uma coluna em csv?
Marci-man
como dar permissão para meu arquivo csv local ser acessado pelo servidor mysql rodando em aws (rds)
rahul
24

Aqui está um script simples de linha de comando PHP que fará o que você precisa:

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

?>

Ele criará uma tabela com base na primeira linha e importará as linhas restantes para ela. Esta é a sintaxe da linha de comando:

php csv_import.php csv_file.csv table_name
Hawkee
fonte
2
Roteiro incrível. Para aqueles com arquivos CSV com aspas duplas (leia a maioria das pessoas), adicione `ENCASED IN '\"' `a fields terminated by ','... funciona até mesmo com CSVs com aspas duplas.
Joel Mellon
3
Acho que você quer dizer ENCLOSED BY '\"'... também, muitas pessoas vão precisar LINES TERMINATED BY '\r\n'se usar um CSV do Windows. E, finalmente, escapar os nomes dos campos com crases é aconselhável, caso haja espaços:$columns .= "`$column` varchar(250)";
dlo
1
Esta resposta é muito melhor do que a resposta aceita. Em particular, permite o que o OP pediu, e eu também quero: "a primeira linha de dados seja usada como os nomes das colunas". (Eu preferiria um script em Python, então não preciso instalar o PHP, mas não deve ser difícil portá-lo.)
LarsH
2
@YumYumYum Você pode explicar melhor o problema que está tendo?
Hawkee
Posso te pagar uma cerveja?
Joe
4

se você tiver a capacidade de instalar o phpadmin, há uma seção de importação onde você pode importar arquivos csv para o seu banco de dados, há até uma caixa de seleção para definir o cabeçalho para a primeira linha do arquivo que contém os nomes das colunas da tabela (se estiver desmarcada, a a primeira linha se tornará parte dos dados

Jose Ortiz
fonte
Estou realmente surpreso que você tenha que usar um add-on como o phpadmin para obter essa funcionalidade, obrigado por sua resposta
chrisfs
Isso me fez ganhar o dia
Marcos,
4

Primeiro crie uma tabela no banco de dados com o mesmo número de colunas que estão no arquivo csv.

Em seguida, use a seguinte consulta

LOAD DATA INFILE 'D:/Projects/testImport.csv' INTO TABLE cardinfo
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
Mukesh
fonte
que tal se eu gostaria de ignorar uma coluna em csv?
Marci-man
3

Para carregar dados de um arquivo de texto ou arquivo csv, o comando é

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

No comando acima, no meu caso, há apenas uma coluna a ser carregada, portanto não há "encerrado por" e "encerrado por", portanto, mantive-o vazio, caso contrário o programador pode inserir o caractere de separação. por exemplo. , (vírgula) ou "ou; ou qualquer coisa.

** para pessoas que usam o mysql versão 5 e superior **

Antes de carregar o arquivo no mysql deve garantir que abaixo da linha de reboque são adicionados na lateral etc/mysql/my.cnf

editar o comando my.cnf é

sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  
Rakesh
fonte
3

Se você iniciar o mysql como "mysql -u -p --local-infile", ele funcionará bem

marciomolusco
fonte
2

Eu escrevi alguns códigos para fazer isso, vou colocar alguns trechos:

$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

Em seguida, obtenha os cabeçalhos CSV para que possa dizer ao mysql como importar (nota: certifique-se de que as colunas do mysql correspondem exatamente às colunas csv):

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

Em seguida, envie sua consulta para o 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
fonte
1

Lutei com isso por algum tempo. O problema não está em como carregar os dados, mas em como construir a tabela para armazená-los. Você deve gerar uma instrução DDL para construir a tabela antes de importar os dados.

Particularmente difícil se a tabela tiver um grande número de colunas.

Aqui está um script Python que (quase) faz o trabalho:

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

O problema que falta resolver é que o nome do campo final e a declaração do tipo de dados terminam com uma vírgula, e o analisador mySQL não tolera isso.

Claro que também tem o problema de usar o tipo de dados TEXT para todos os campos. Se a tabela tiver várias centenas de colunas, VARCHAR (64) tornará a tabela muito grande.

Isso também parece quebrar na contagem máxima de colunas para mySQL. É quando é hora de mudar para Hive ou HBase, se você puder.

agentev
fonte
1

Veja como fiz em Python usando csv e o conector 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()

Pontos chave

  • Use instruções preparadas para o INSERT
  • Abra o arquivo.csv em 'rb'binário
  • Alguns arquivos CSV podem precisar de ajustes , como a skipinitialspaceopção.
  • Se 255não for grande o suficiente, você obterá erros em INSERT e terá que começar de novo.
  • Ajuste os tipos de coluna, por exemplo ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • Adicione uma chave primária , por exemploALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;
Bob Stein
fonte
0

Importar arquivos CSV para a tabela 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
fonte
0

Como outros mencionaram, o infile local de dados de carga funciona muito bem. Eu tentei o script php que Hawkee postou, mas não funcionou para mim. Em vez de depurar, aqui está o que fiz:

1) copie / cole a linha de cabeçalho do arquivo CSV em um arquivo txt e edite com emacs. adicione uma vírgula e um CR entre cada campo para colocar cada um em sua própria linha.
2) Salve esse arquivo como FieldList.txt
3) edite o arquivo para incluir defns para cada campo (a maioria era varchar, mas alguns eram int (x). Adicione criar tabela tablename (no início do arquivo e) ao fim do arquivo. Salve-o como CreateTable.sql
4) inicie o cliente mysql com a entrada do arquivo Createtable.sql para criar a tabela
5) inicie o cliente mysql, copie / cole a maior parte do comando 'LOAD DATA INFILE' que substitui minha tabela nome e nome do arquivo csv. Cole no arquivo FieldList.txt. Certifique-se de incluir 'IGNORE 1 LINES' antes de colar na lista de campos

Parece muito trabalho, mas fácil com emacs .....

Jim sims
fonte
0

Use o aplicativo TablePlus: Clique com o botão direito do mouse no nome da tabela no painel direito Escolha Importar ...> De CSV Escolha arquivo CSV Revise a correspondência de coluna e clique em Importar Tudo pronto!

Milad Hatami
fonte
-3

Eu tenho várias maneiras de pesquisar no google para importar csv para mysql, incluir "load data infile", usar mysql workbench, etc.

quando eu uso o botão de importação do mysql workbench, primeiro você precisa criar a tabela vazia por conta própria, definir cada tipo de coluna por conta própria. Nota: você deve adicionar a coluna ID no final como chave primária e não nula e auto_increment, caso contrário, o botão de importação não ficará visível posteriormente. No entanto, quando eu começo a carregar o arquivo CSV, nada carregado, parece um bug. Desisto.

Sorte, a melhor maneira fácil que encontrei até agora é usar o mysql da Oracle para excel. você pode baixá-lo aqui mysql para excel

Isto é o que você vai fazer: abrir o arquivo csv no excel, na aba Dados, localizar mysql para o botão excel

selecione todos os dados, clique em exportar para mysql. Nota para definir uma coluna de ID como chave primária.

quando terminar, vá para o ambiente de trabalho mysql para alterar a tabela, como o tipo de moeda deve ser decimal (19,4) para decimal grande (10,2) para uso regular. outro tipo de campo pode ser definido como varchar (255).

Hoogw
fonte