Jak zaimportować plik CSV do tabeli MySQL?

306

Mam nienormalizowany dziennik zdarzeń CSV od klienta, który próbuję załadować do tabeli MySQL, abym mógł przefakturować go do rozsądnego formatu. Utworzyłem tabelę o nazwie „CSVImport”, która ma jedno pole dla każdej kolumny pliku CSV. Plik CSV zawiera 99 kolumn, więc samo w sobie było to dość trudne zadanie:

CREATE TABLE 'CSVImport' (id INT);
ALTER TABLE CSVImport ADD COLUMN Title VARCHAR(256);
ALTER TABLE CSVImport ADD COLUMN Company VARCHAR(256);
ALTER TABLE CSVImport ADD COLUMN NumTickets VARCHAR(256);
...
ALTER TABLE CSVImport Date49 ADD COLUMN Date49 VARCHAR(256);
ALTER TABLE CSVImport Date50 ADD COLUMN Date50 VARCHAR(256);

Tabela nie zawiera żadnych ograniczeń, a wszystkie pola zawierają wartości VARCHAR (256), z wyjątkiem kolumn zawierających liczby (reprezentowane przez INT), tak / nie (reprezentowane przez BIT), ceny (reprezentowane przez DECIMAL) i blurb tekstowy ( reprezentowany przez TEKST).

Próbowałem załadować dane do pliku:

LOAD DATA INFILE '/home/paul/clientdata.csv' INTO TABLE CSVImport;
Query OK, 2023 rows affected, 65535 warnings (0.08 sec)
Records: 2023  Deleted: 0  Skipped: 0  Warnings: 198256
SELECT * FROM CSVImport;
| NULL             | NULL        | NULL           | NULL | NULL               | 
...

Cały stół jest wypełniony NULL.

Myślę, że problem polega na tym, że blobty tekstowe zawierają więcej niż jedną linię, a MySQL analizuje plik tak, jakby każda nowa linia odpowiadała jednemu wierszowi bazy danych. Mogę bez problemu załadować plik do OpenOffice.

Plik clientdata.csv zawiera 2593 wierszy i 570 rekordów. Pierwszy wiersz zawiera nazwy kolumn. Myślę, że jest rozdzielany przecinkami, a tekst jest najwyraźniej rozdzielany podwójnym cudzysłowem.

AKTUALIZACJA:

W razie wątpliwości przeczytaj instrukcję: http://dev.mysql.com/doc/refman/5.0/en/load-data.html

Dodałem trochę informacji do LOAD DATAstwierdzenia, że ​​OpenOffice był wystarczająco inteligentny, aby wnioskować, a teraz ładuje prawidłową liczbę rekordów:

LOAD DATA INFILE "/home/paul/clientdata.csv"
INTO TABLE CSVImport
COLUMNS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;

Ale nadal istnieje wiele całkowicie NULLzapisów i żadne z załadowanych danych nie wydają się być odpowiednie.

Iain Samuel McLean Elder
źródło
17
A jeśli korzystasz z OSX Sequel Pro ma niesamowite narzędzie do importowania i jest BEZPŁATNE ;-)
Merrick
41
To dla mnie niesamowite, że oryginalny plakat odpowiedział na własne pytanie lepiej niż ktokolwiek inny ... Nie wiem, dlaczego tak wielu ludzi jest tak gotowych udzielać rekomendacji oprogramowania, gdy istnieje istniejące polecenie SQL, które może być programowe, a nie interfejs użytkownika -na podstawie. Nie wiem o nikim innym, ale programmatic oznacza dla mnie, że mogę mieć skrypty skonfigurowane do automatycznego importowania plików na znacznikach czasu, podczas gdy oparty na interfejsie użytkownika jest wyłącznie ręczny.
Chris Cirefice,
@ChrisCirefice: Myślę, że zaakceptowana odpowiedź wyjaśnia to dobrze. Potrzebował pomocy w ręcznym utworzeniu polecenia „ładuj dane”, w czym może pomóc program graficzny. Po utworzeniu przez program graficzny polecenia „wczytaj dane”, może on ponownie użyć go programowo.
AlexC
@Merrick to działało na osx
weaveoftheride

Odpowiedzi:

133

Rdzeniem problemu wydaje się być dopasowanie kolumn w pliku CSV do kolumn w tabeli.

Wiele graficznych klientów mySQL ma bardzo ładne okna dialogowe importu do tego rodzaju rzeczy.

Moim ulubionym do pracy jest HeidiSQL oparty na systemie Windows . Daje graficzny interfejs do budowania LOAD DATApolecenia; możesz go ponownie użyć programowo później.

Importuj plik tekstowy

Zrzut ekranu: okno dialogowe „Importuj plik tekstowy”

Aby otworzyć okno dialogowe Importuj plik tekstowy ”, przejdź do Tools > Import CSV file:

wprowadź opis zdjęcia tutaj

Pekka
źródło
25
W systemie Mac OSX użyj Sequel Pro.
Agi Hammerthief,
3
Właśnie go wypróbowałem i najpierw muszę utworzyć tabelę ... zamiast używać nazw kolumn.
Dominique,
3
Musisz wybrać stolik, zanim będziesz mógł kontynuować ... i ponieważ cały ten punkt nie musi robić stołu ...
Dominique
3
Zauważ, że w Linuksie HeidiSQL działa bardzo dobrze pod Wine.
AlejandroVD
1
@Paul sam sedno odpowiedzi jest takie, że narzędzia GUI mogą ułatwić dopasowanie kolumn importu do kolumn tabeli.
Pekka,
191

Użyj mysqlimport, aby załadować tabelę do bazy danych:

mysqlimport --ignore-lines=1 \
            --fields-terminated-by=, \
            --local -u root \
            -p Database \
             TableName.csv

Znalazłem to na http://chriseiffel.com/everything-linux/how-to-import-a-large-csv-file-to-mysql/

Aby ustawić ogranicznik jako kartę, użyj --fields-terminated-by='\t'

Michalzuber
źródło
6
mysqlimportużywa LOAD DATA INFILE...za kulisami, więc jest prawie tak samo.
Mladen Jablanović
8
Tak jak w przypadku LOAD DATA INFILE, musisz utworzyć tabelę, zanim będziesz mógł z niej korzystać mysqlimport.
Marcus Downing,
@ MladenJablanović, to zdecydowanie nie to samo. Spróbuj zaimportować 1bil wierszy. Będziesz zaskoczony, jak ogromną różnicę to robi pod względem wydajności
ninjabber 18.04.16
@ninjabber Dokumenty mówią, że klient mysqlimport zapewnia interfejs wiersza poleceń do pliku LOAD DATA INFILE , więc teoretycznie niemożliwe jest zaoferowanie jakichkolwiek korzyści w zakresie wydajności LOAD DATA INFILE.
Mladen Jablanović
1
także potrzebują --fields-optionally-enclosed-by=\"i `--fields-escaped-by = \`
chaintng
80

Najprostszym sposobem, który zaimportowałem ponad 200 wierszy jest polecenie poniżej w oknie phpmyadmin sql

Mam prostą tabelę kraju z dwiema kolumnami CountryId, CountryName

tutaj są dane .csvPLIK CSV

oto polecenie:

LOAD DATA INFILE 'c:/country.csv' 
INTO TABLE country 
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS

Pamiętaj o jednej rzeczy, nigdy nie pojawiaj się w drugiej kolumnie, w przeciwnym razie import zostanie zatrzymany

Śmiałek
źródło
1
',' -> '\ t', '"' -> '' w przypadku plików TSV i usuń ostatni wiersz, jeśli nie ma nagłówka. (Mam nadzieję, że przeszukiwacze indeksują to).
Bleeding Fingers
16
Jeśli jest to plik lokalny, może być konieczne LOAD DATA LOCAL INFILE. Jeśli spowoduje to błąd 1148 „użyte polecenie nie jest dozwolone”, możesz je włączyć, uruchamiając mysql w wierszu polecenia za pomocą --local-infile.
Big McLargeHuge
dostałem błąd: BŁĄD 1045 (28000): Odmowa dostępu dla użytkownika „użytkownik” @ „%” (przy użyciu hasła: TAK)
ARUNBALAN NV
Musisz przyznać cały dostęp użytkownikowi, następnie z panelu administracyjnego spróbuj zaimportować skrypt.
DareDevil
1
Pojawia się ten błąd: serwer MySQL działa z opcją --secure-file-priv, więc nie może wykonać tej instrukcji
Agniswar Bakshi
66

Wiem, że pytanie jest stare , ale chciałbym się tym podzielić

Użyłem tej metody do zaimportowania ponad 100 000 rekordów ( ~ 5 MB ) w 0,046 s

Oto jak to zrobić:

LOAD DATA LOCAL INFILE  
'c:/temp/some-file.csv'
INTO TABLE your_awesome_table  
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(field_1,field_2 , field_3);

Bardzo ważne jest dołączenie ostatniego wiersza, jeśli masz więcej niż jedno pole, tzn. Zwykle pomija ostatnie pole (MySQL 5.6.17)

LINES TERMINATED BY '\n'
(field_1,field_2 , field_3);

Następnie, zakładając, że masz pierwszy wiersz jako tytuł swoich pól, możesz również chcieć dołączyć ten wiersz

IGNORE 1 ROWS

Tak to wygląda, jeśli plik ma wiersz nagłówka.

LOAD DATA LOCAL INFILE  
'c:/temp/some-file.csv'
INTO TABLE your_awesome_table  
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(field_1,field_2 , field_3);
Fahad
źródło
Zaimportowałem 16 tys. Wierszy i 48 kolumn. Dziękuję kolego.
Renjith VR
To najlepsze rozwiązanie. Dla każdego, kto jest ciekawy, jak szybko to jest: Zaimportowałem 3,2 miliona wierszy w mniej niż 14 sekund na instancji Lightsail AWS 20 USD / mc z wbudowanym serwerem MySQL (nie wydajnym RDS). Niesamowite!
master_gracey,
Czy w tym wierszu (field_1,field_2 , field_3);odnosi się do listy kolumn w pliku .csv lub w tabeli? tj. jakie są te pola?
tera_789,
@ tera_789 Te w twoim pliku csv, które prawdopodobnie pasują do twojego stołu
Fahad
Musi być zgodny z formatem danych. przykład (w moim przypadku) <pre> imię, nazwisko, dob, numer telefonu, adres e-mail, imię, nazwisko, 12-05-2018,54545, faiz @ gmail.com, nazwa1, nazwisko 1,2018-05-12,456, faiz1 @ gmail .com, name2, lastName2,2018-05-12,456, faiz2 @ gmail.com, name3, lastName3,2018-05-22,456, faiz3 @ gmail.com, name4, lastName4,1988-05-22,456, faiz4 @ gmail.com , name5, lastName5,1988-05-22,456, faiz5 @ gmail.com, name6, lastName6,1987-05-21,456, faiz6 @ gmail.com </pre>
Faiz Ahmed
32

phpMyAdmin może obsłużyć import CSV. Oto kroki:

  1. Przygotuj plik CSV, aby pola były w tej samej kolejności, co pola tabeli MySQL.

  2. Usuń wiersz nagłówka z pliku CSV (jeśli istnieje), aby w pliku były tylko dane.

  3. Przejdź do interfejsu phpMyAdmin.

  4. Wybierz tabelę w menu po lewej stronie.

  5. Kliknij przycisk importu u góry.

  6. Przejdź do pliku CSV.

  7. Wybierz opcję „CSV za pomocą LOAD DATA”.

  8. Wpisz „,” w „polach zakończonych przez”.

  9. Wprowadź nazwy kolumn w tej samej kolejności, w jakiej znajdują się w tabeli bazy danych.

  10. Kliknij przycisk Idź i gotowe.

To jest uwaga, którą przygotowałem do mojego przyszłego użytku i dzielę się tutaj, jeśli ktoś inny może skorzystać.

Farhan
źródło
To jest dobre i proste. Wolę tworzyć tabele i kolumny za pomocą SQL (więc pomijam krok # 9) i wstawiam dane poprzez import CSV. Nie zapomnij ustawić NULLw pliku CSV dla pól / kolumn z automatyczną inkrementacją.
srebrny
Zauważ, że phpMyAdmin kończy się niepowodzeniem, gdy znaki cyrylicy są zawarte w pliku CSV, bez względu na to, czy chcesz używać utf-8.
Fran Marzoa
Nie zapomnij zmienić rozmiaru importu, jeśli importujesz duży plik CSV. BTW to nie jest dobra opcja dla dużych plików CSV.
Avi
Wymaga to najpierw pobrania pliku .csv do klienta WWW, ponieważ nie można przeglądać lokalnego pliku csv.
mckenzm
Tak, możesz, musisz zaznaczyć pole wyboru „Lokalne słowo kluczowe” i możesz użyć lokalnego pliku csv
chrisfs
12

Możesz to naprawić, wyświetlając kolumny w instrukcji LOAD DATA. Z instrukcji :

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);

... więc w twoim przypadku musisz wymienić 99 kolumn w kolejności, w jakiej pojawiają się w pliku csv.

Lafncow
źródło
8

Spróbuj, to zadziałało dla mnie

    LOAD DATA LOCAL INFILE 'filename.csv' INTO TABLE table_name FIELDS TERMINATED BY ',' ENCLOSED BY '"' IGNORE 1 ROWS;

IGNORE 1 ROWS tutaj ignoruje pierwszy wiersz, który zawiera nazwy pól. Zauważ, że w nazwie pliku musisz wpisać bezwzględną ścieżkę do pliku.

David
źródło
To najlepsza odpowiedź. Po co używać innego narzędzia, jeśli wystarczy pojedyncze polecenie SQL?
sdgfsdh
Czy wiesz, jak to zrobić, gdy próbujesz załadować plik do mysql działającego na serwerze? Pyta mnie odmowa dostępu do pliku (hasło). Gdzie wpisać hasło do lokalizacji pliku csv?
Baktaawar
7

Wiersz polecenia mysql jest podatny na zbyt wiele problemów podczas importowania. Oto jak to zrobić:

  • użyj programu Excel do edycji nazw nagłówków, aby nie miały spacji
  • zapisz jako .csv
  • użyj darmowej przeglądarki Navicat Lite Sql do importowania i automatycznego tworzenia nowej tabeli (nadaj jej nazwę)
  • otwórz nową tabelę wstaw kolumnę podstawowego numeru auto dla ID
  • zmień typ kolumn według potrzeb.
  • gotowy!
użytkownik 1464271
źródło
5

Jeśli używasz MySQL Workbench (obecnie wersja 6.3), możesz to zrobić przez:

  1. Kliknij prawym przyciskiem myszy „Tabele”;
  2. Wybierz Kreatora importu danych tabeli;
  3. Wybierz plik csv i postępuj zgodnie z instrukcjami (można również użyć JSON); Dobrą rzeczą jest to, że możesz utworzyć nową tabelę na podstawie pliku csv, który chcesz zaimportować lub załadować dane do istniejącej tabeli

wprowadź opis zdjęcia tutaj

Vitaliy Pak
źródło
+1. Użyłem tego, ponieważ mysql ciągle dawał mi błędy LOAD DATA INFILEi mysqlimport(„nie jest to obsługiwane w tej wersji mysql”)
clmno
Ta metoda działa, ale jest trochę powolna. Myślałam, że użycie tej funkcji zbudowałoby ogromne INSERTzapytanie i spróbowałbym zrobić to wszystko naraz, ale wygląda na to, że robienie tego w ten sposób działa raz INSERTna rząd.
DaveTheMinion,
4

Widzę coś dziwnego. Używasz do UCIECZKI tego samego znaku, którego używasz do ZAKOŃCZENIA. Tak więc silnik nie wie, co zrobić, gdy znajdzie „” i myślę, że dlatego wydaje się, że nic nie jest we właściwym miejscu. Myślę, że jeśli usuniesz linię ESCAPING, powinno działać świetnie.

LOAD DATA INFILE "/home/paul/clientdata.csv"
INTO TABLE CSVImport
COLUMNS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;

Chyba że przeanalizujesz (ręcznie, wizualnie ...) swój plik CSV i znajdziesz, która postać używa do ucieczki. Czasami jest „\”. Ale jeśli go nie masz, nie używaj go.

Juan
źródło
3

Jeszcze innym rozwiązaniem jest użycie narzędzia csvsql z niesamowitego pakietu csvkit .

Przykład użycia:

csvsql --db mysql://$user:$password@localhost/$database --insert --tables $tablename  $file

To narzędzie może automatycznie wnioskować o typach danych (zachowanie domyślne), utworzyć tabelę i wstawić dane do utworzonej tabeli. --overwriteOpcji można użyć do usunięcia tabeli, jeśli już istnieje.--insertopcja - aby wypełnić tabelę z pliku.

Aby zainstalować pakiet

pip install csvkit

Wymagania: python-dev , libmysqlclient-dev,MySQL-python

apt-get install python-dev libmysqlclient-dev
pip install MySQL-python
ruvim
źródło
3

Jak importować pliki csv do tabel sql

Przykładowy plik: plik Overseas_trade_indexCSV danych

Kroki:

  1. Musisz utworzyć tabelę dla overseas_trade_index.

  2. Musisz utworzyć kolumny związane z plikiem csv.

    Zapytanie SQL:

    ( id int not null primary key auto_increment,
    series_reference varchar (60),
    period varchar (60),
    data_value decimal(60,0),
    status varchar (60),
    units varchar (60),
    magnitude int(60),
    subject text(60),
    group text(60),
    series_title_1 varchar (60),
    series_title_2 varchar (60),
    series_title_3 varchar (60),
    series_title_4 varchar (60),
    series_title_5 varchar (60),
     );
  3. Musisz podłączyć bazę danych mysql w terminalu.

    =>show databases;
    =>use database;
    =>show tables;
  4. Wprowadź to polecenie, aby zaimportować dane csv do tabel mysql.

    load data infile '/home/desktop/Documents/overseas.csv' into table trade_index fields terminated by ',' lines terminated by '\n' (series_reference,period,data_value,status,units,magnitude,subject,series_title1,series_title_2,series_title_3,series_title_4,series_title_5);
  5. Znajdź te dane indeksu handlu zagranicznego w sqldatabase:

    select * from trade_index;
sivamani
źródło
2

Jeśli używasz komputera z systemem Windows z załadowanym arkuszem kalkulacyjnym Excel, nowa wtyczka mySql do programu Excel jest fenomenalna. Ludzie w Oracle naprawdę wykonali niezłą robotę przy tym oprogramowaniu. Możesz wykonać połączenie z bazą danych bezpośrednio z Excela. Wtyczka przeanalizuje Twoje dane i utworzy dla Ciebie tabele w formacie zgodnym z danymi. Miałem kilka dużych plików CSV z danymi do konwersji. To narzędzie pozwoliło zaoszczędzić dużo czasu.

http://dev.mysql.com/downloads/windows/excel/

Możesz dokonywać aktualizacji z poziomu Excela, które zostaną wprowadzone do bazy danych online. Działa to wyjątkowo dobrze z plikami mySql utworzonymi na bardzo niedrogim hostingu współdzielonym GoDaddy. (Uwaga: gdy tworzysz tabelę w GoDaddy, musisz wybrać niestandardowe ustawienia, aby umożliwić dostęp do bazy danych poza witryną ...)

Dzięki tej wtyczce masz czystą interaktywność między arkuszem kalkulacyjnym XL a internetowym magazynem danych mySql.

zipzit
źródło
2

Używam mysql workbench do wykonania tej samej pracy.

  1. utwórz nowy schemat
  2. otwórz nowo utworzony schemat
  3. kliknij prawym przyciskiem myszy „Tabele” i wybierz „Kreator importu danych tabeli”
  4. podaj ścieżkę do pliku csv i nazwę tabeli, a następnie skonfiguruj typ kolumny, ponieważ kreator ustawia domyślny typ kolumny na podstawie ich wartości.

Uwaga: spójrz na plik dziennika mysql workbench pod kątem błędów, używając „tail -f [mysqlworkbenchpath] /log/wb*.log”

Mehdi
źródło
Bardzo dziękuję za odpowiedź - będąc nowym w MySQL, nie wiedziałem o tym - pomogło mi to w CSV. Teraz muszę również zaimportować 10 tabel z programu Access - czy uważasz, że najprostszym sposobem będzie wyeksportowanie tych tabel do programu Excel, z programu Excel do pliku CSV, a następnie skorzystanie z tych kroków?
Naomi
Odkryłem, że ta metoda nie importuje wszystkich wierszy :( Z 5 342 wierszy zaimportowała tylko 2485 wierszy. Dlaczego to?
Naomi
Hej Naomi, jeśli sprawdzisz dziennik mysqlworkbench, pokaże ci, dlaczego przestał importować dane. W pliku DB i CSV mogą znajdować się wartości null lub typ niezgodności. Ale bardzo polecam podążać za odpowiedzią Juana (zaraz za mną). Jego rozwiązanie jest lepsze i czystsze ode mnie.
Mehdi
1

Oto przykładowy zrzut ekranu pliku Excel:

wprowadź opis zdjęcia tutaj

Zapisz jako i wybierz .csv.

Będziesz miał, jak pokazano poniżej, zrzut ekranu .csv, jeśli otworzysz za pomocą notatnika ++ lub innego notatnika.

wprowadź opis zdjęcia tutaj

Upewnij się, że usunąłeś nagłówek i wyrównywałeś kolumny w .csv jak w tabeli mysql. Zastąp folder_name nazwą swojego folderu

LOAD DATA LOCAL INFILE
„D: /folder_name/myfilename.csv„ DO TABELI Poczta POLE ZAKOŃCZONE PRZEZ ”,„ (fname, lname, email, telefon);

W przypadku dużych zbiorów danych możesz wziąć kawę i załadować ją !.

To wszystko czego potrzebujesz.

Magige Daniel
źródło
0

Kwerenda PHP dotycząca importu pliku csv do bazy danych mysql

$query = <<<EOF
            LOAD DATA LOCAL INFILE '$file'
             INTO TABLE users
             FIELDS TERMINATED BY ','
             LINES TERMINATED BY '\n'
             IGNORE 1 LINES
            (name,mobile,email)
    EOF;
if (!$result = mysqli_query($this->db, $query))
   {
        exit(mysqli_error($this->db));
   }

** Przykładowe dane pliku CSV **

name,mobile,email
Christopher Gritton,570-686-3439,ChristopherKGritton@inbound.plus
Brandon Wilson,541-309-5149,BrandonMWilson@inbound.plus
Craig White,516-795-8065,CraigJWhite@inbound.plus
David Whitney,713-214-3966,DavidCWhitney@inbound.plus
Suwarnakumar Kanapathipillai
źródło
0

Zmień nazwę serwera, nazwę użytkownika, hasło, nazwę db, ścieżkę pliku, tablename i pole znajdujące się w bazie danych, którą chcesz wstawić

<?php
    $servername = "localhost";
    $username = "root";
    $password = "";
    $dbname = "bd_dashboard";
    //For create connection
    $conn = new mysqli($servername, $username, $password, $dbname);

    $query = "LOAD DATA LOCAL INFILE 
                'C:/Users/lenovo/Desktop/my_data.csv'
                INTO TABLE test_tab
                FIELDS TERMINATED BY ','
                LINES TERMINATED BY '\n'
                IGNORE 1 LINES
                (name,mob)";
    if (!$result = mysqli_query($conn, $query)){
        echo '<script>alert("Oops... Some Error occured.");</script>';
        exit();
            //exit(mysqli_error());
       }else{
        echo '<script>alert("Data Inserted Successfully.");</script>'
       }
    ?>
Srikrushna
źródło