Importuj CSV do tabeli mysql


96

Jaki jest najlepszy / najszybszy sposób przesłania pliku csv do tabeli mysql? Chciałbym, aby pierwszy wiersz danych był używany jako nazwy kolumn.

Znajdź to:

Jak zaimportować plik CSV do tabeli MySQL

Ale jedyną odpowiedzią było użycie GUI, a nie powłoki?


3
I nawet rozwiązanie GUI nie pobiera nazw kolumn z csv ... przed importem musisz utworzyć całą tabelę
Dominique

To pytanie ma już odpowiedź tutaj stackoverflow.com/questions/3635166/…
David

odpowiedź zaakceptowana na pytanie, do którego tworzysz łącze, zawierała GUI. Odpowiedź, którą jesteście referencjami, została udzielona wczoraj, podczas gdy to pytanie (odpowiedź) pochodzi z 2012 r.
lcm

Odpowiedzi:


147

Zamiast pisać skrypt pobierający informacje z pliku CSV, możesz bezpośrednio połączyć z nim MYSQL i przesłać informacje przy użyciu następującej składni SQL.

Aby zaimportować plik Excel do MySQL, najpierw wyeksportuj go jako plik CSV. Usuń nagłówki CSV z wygenerowanego pliku CSV wraz z pustymi danymi, które program Excel mógł umieścić na końcu pliku CSV.

Następnie możesz zaimportować go do tabeli MySQL, uruchamiając:

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

jak czytano: Importuj plik CSV bezpośrednio do MySQL

EDYTOWAĆ

W twoim przypadku musisz najpierw napisać interpretera, aby znaleźć pierwszy wiersz i przypisać je jako nazwy kolumn.


EDYCJA-2

Z dokumentacji MySQL na temat LOAD DATAskładni :

Ta IGNORE number LINESopcja może służyć do ignorowania wierszy na początku pliku. Na przykład możesz użyć, IGNORE 1 LINESaby pominąć początkową linię nagłówka zawierającą nazwy kolumn:

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

Dlatego możesz użyć następującej instrukcji:

LOAD DATA LOCAL INFILE 'uniq.csv'
INTO TABLE tblUniq
FIELDS TERMINATED BY ','
    ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(uniqName, uniqCity, uniqComments)

8
Zamiast usuwać pierwszą linię, możesz dodać IGNORE 1 LINESdo zapytania
mb14

Czy wiesz, czy istnieje sposób na ustawienie ścieżki do pliku csv?
JasonDavis

Jak debugować to polecenie, gdy się nie powiedzie? Próbuję załadować plik za pomocą tego polecenia, ale nic nie robi.

co powiesz na to, że chciałbym zignorować kolumnę w csv?
Marci-man

jak zezwolić na dostęp do mojego lokalnego pliku csv przez serwer mysql działający na aws (rds)
rahul

24

Oto prosty skrypt wiersza poleceń PHP, który zrobi to, czego potrzebujesz:

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

?>

Utworzy tabelę na podstawie pierwszego wiersza i zaimportuje do niej pozostałe wiersze. Oto składnia wiersza poleceń:

php csv_import.php csv_file.csv table_name

2
Niesamowity skrypt. Dla tych z plikami CSV z podwójnymi cudzysłowami (czytaj większość ludzi) dodaj `` ENCASED IN '\ "' 'do fields terminated by ','... działa nawet z plikami CSV z częściowo podwójnymi cudzysłowami.
Joel Mellon

3
Myślę, że masz na myśli ENCLOSED BY '\"'... także, wiele osób będzie potrzebować, LINES TERMINATED BY '\r\n'jeśli użyjesz CSV z Windows. I wreszcie, ucieczka od nazw pól grawitami jest mądra, jeśli są spacje:$columns .= "`$column` varchar(250)";
dlo

1
Ta odpowiedź jest znacznie lepsza niż zaakceptowana odpowiedź. W szczególności dopuszcza to, o co prosił PO, a ja również chcę: „pierwszy wiersz danych może być użyty jako nazwy kolumn”. (Wolałbym skrypt w Pythonie, więc nie muszę instalować PHP, ale przeniesienie go nie powinno być trudne.)
LarsH

2
@YumYumYum Czy możesz bardziej szczegółowo omówić problem, który masz?
Hawkee,

Mogę ci kupić piwo?
Joe,

4

jeśli masz możliwość zainstalowania phpadmina, jest sekcja importu, w której możesz importować pliki csv do bazy danych, jest nawet pole wyboru, aby ustawić nagłówek w pierwszej linii pliku zawierającej nazwy kolumn tabeli (jeśli jest odznaczone, pierwsza linia stanie się częścią danych


Jestem naprawdę zaskoczony, że musisz użyć dodatku takiego jak phpadmin, aby uzyskać tę funkcjonalność.Dzięki za odpowiedź
chrisfs

To właśnie sprawiło, że mój dzień
Mark

4

Najpierw utwórz tabelę w bazie danych z taką samą liczbą kolumn, jak w pliku csv.

Następnie użyj następującego zapytania

LOAD DATA INFILE 'D:/Projects/testImport.csv' INTO TABLE cardinfo
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'

co powiesz na to, że chciałbym zignorować kolumnę w csv?
Marci-man

3

Aby załadować dane z pliku tekstowego lub pliku csv, poleceniem jest

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

W powyższym poleceniu w moim przypadku jest tylko jedna kolumna do załadowania, więc nie ma "zakończonych przez" i "zamkniętych przez", więc zostawiłem to puste, w przeciwnym razie programista może wprowadzić znak oddzielający. np. , (przecinek) lub „lub; lub cokolwiek innego.

** dla osób, które używają mysql w wersji 5 i nowszych **

Przed załadowaniem pliku do mysql należy upewnić się, że poniższe linie holownicze są dodane z boku etc/mysql/my.cnf

aby edytować polecenie my.cnf to

sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  


2

Napisałem kod, aby to zrobić, wstawię kilka fragmentów:

$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

Następnie pobierz nagłówki CSV, abyś mógł powiedzieć mysql, jak importować (uwaga: upewnij się, że kolumny mysql dokładnie odpowiadają kolumnom csv):

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

Następnie wyślij zapytanie do serwera 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());

1

Zmagałem się z tym przez jakiś czas. Problem nie polega na tym, jak załadować dane, ale jak skonstruować tabelę do ich przechowywania. Przed zaimportowaniem danych należy wygenerować instrukcję DDL, aby zbudować tabelę.

Szczególnie trudne, jeśli tabela ma dużą liczbę kolumn.

Oto skrypt w Pythonie, który (prawie) wykonuje swoją pracę:

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

Problem, jaki pozostawia do rozwiązania, polega na tym, że ostateczna nazwa pola i deklaracja typu danych jest zakończona przecinkiem, a parser mySQL tego nie toleruje.

Oczywiście ma również problem z tym, że używa typu danych TEKST dla każdego pola. Jeśli tabela ma kilkaset kolumn, to VARCHAR (64) spowoduje, że tabela będzie za duża.

Wydaje się, że to również działa przy maksymalnej liczbie kolumn dla mySQL. Wtedy nadszedł czas, aby przenieść się do Hive lub HBase, jeśli możesz.


1

Oto jak zrobiłem to w Pythonie przy użyciu csv i łącznika 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()

Kluczowe punkty

  • Użyj przygotowanych instrukcji dla WSTAWIANIA
  • Otwórz plik.csv w 'rb'formacie binarnym
  • Niektóre pliki CSV mogą wymagać poprawek , takich jak skipinitialspaceopcja.
  • Jeśli 255nie jest wystarczająco szeroki, na INSERT pojawią się błędy i będziesz musiał zacząć od nowa.
  • Dostosuj typy kolumn, np ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • Dodaj klucz podstawowy , npALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;


0

Jak wspominali inni, lokalny plik ładowania danych działa dobrze. Wypróbowałem skrypt php, który opublikował Hawkee, ale nie zadziałał. Zamiast debugować, oto co zrobiłem:

1) skopiuj / wklej wiersz nagłówka pliku CSV do pliku txt i edytuj za pomocą emacsa. dodaj przecinek i CR między każdym polem, aby umieścić je we własnym wierszu.
2) Zapisz ten plik jako FieldList.txt
3) edytować plik zawierać defns dla każdego pola (większość była varchar, ale sporo było int (x). Dodaj create table nazwa_tabeli (do początku pliku i) do koniec pliku. Zapisz go jako CreateTable.sql
4) uruchom klienta mysql z danymi wejściowymi z pliku Createtable.sql, aby utworzyć tabelę
5) uruchom klienta mysql, skopiuj / wklej większość polecenia „LOAD DATA INFILE” zastępując moją tabelę name i nazwa pliku csv. Wklej w pliku FieldList.txt. Pamiętaj, aby dołączyć „IGNORUJ 1 LINIE” przed wklejeniem do listy pól

Brzmi jak dużo pracy, ale łatwo z emacsem .....


0

Użyj aplikacji TablePlus: Kliknij prawym przyciskiem myszy nazwę tabeli z prawego panelu Wybierz Importuj ...> Z CSV Wybierz plik CSV Przejrzyj dopasowanie kolumn i naciśnij Importuj Wszystko gotowe!


-3

Mam wyszukiwarkę Google na wiele sposobów importowania csv do mysql, w tym „załaduj plik danych”, używam Środowiska pracy mysql itp.

kiedy używam przycisku importu mysql workbench, najpierw musisz samodzielnie stworzyć pustą tabelę, ustawić każdy typ kolumny samodzielnie. Uwaga: musisz dodać kolumnę ID na końcu jako klucz podstawowy, a nie null i auto_increment, w przeciwnym razie przycisk importu nie będzie widoczny później. Jednak kiedy zaczynam ładować plik CSV, nic nie jest ładowane, wygląda na to, że jest to błąd. Poddaję się.

Na szczęście najlepszym sposobem, jaki do tej pory znalazłem, jest użycie mysql Oracle dla programu Excel. możesz go pobrać stąd mysql for excel

Oto, co zamierzasz zrobić: otwórz plik csv w programie Excel, na karcie Dane, znajdź przycisk mysql dla programu Excel

wybierz wszystkie dane, kliknij eksport do mysql. Uwaga, aby ustawić kolumnę ID jako klucz podstawowy.

po zakończeniu przejdź do Środowiska pracy mysql, aby zmienić tabelę, na przykład typ waluty powinien być dziesiętny (19,4) dla dużej ilości dziesiętnej (10,2) do regularnego użytku. inny typ pola może być ustawiony na varchar (255).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.