Importieren Sie CSV in die MySQL-Tabelle

95

Was ist der beste / schnellste Weg, um eine CSV-Datei in eine MySQL-Tabelle hochzuladen? Ich möchte für die erste Datenzeile als Spaltennamen verwendet werden.

Ich habe es gefunden:

So importieren Sie eine CSV-Datei in eine MySQL-Tabelle

Aber die einzige Antwort war, eine GUI und keine Shell zu verwenden?

lcm
quelle
3
Und selbst die GUI-Lösung übernimmt nicht die Spaltennamen aus der CSV ... Sie müssen die gesamte Tabelle vor dem Import erstellen
Dominique
Die Frage hat hier bereits eine Antwort stackoverflow.com/questions/3635166/…
David
Die Antwort auf die Frage, auf die Sie verlinken, wurde über eine GUI akzeptiert. Die Antwort, auf die Sie sich beziehen, wurde gestern bereitgestellt, während diese Frage (Antwort) aus dem Jahr 2012 stammt.
lcm

Antworten:

146

Anstatt ein Skript zum Abrufen von Informationen aus einer CSV-Datei zu schreiben, können Sie MYSQL direkt damit verknüpfen und die Informationen mithilfe der folgenden SQL-Syntax hochladen.

Um eine Excel-Datei in MySQL zu importieren, exportieren Sie sie zunächst als CSV-Datei. Entfernen Sie die CSV-Header aus der generierten CSV-Datei zusammen mit leeren Daten, die Excel möglicherweise am Ende der CSV-Datei eingefügt hat.

Sie können es dann in eine MySQL-Tabelle importieren, indem Sie Folgendes ausführen:

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

Lesen Sie weiter: Importieren Sie die CSV-Datei direkt in MySQL

BEARBEITEN

Für Ihren Fall müssen Sie zuerst einen Interpreter schreiben, um die erste Zeile zu finden und sie als Spaltennamen zuzuweisen.


EDIT-2

Aus MySQL-Dokumenten zur LOAD DATASyntax :

Mit dieser IGNORE number LINESOption können Zeilen am Anfang der Datei ignoriert werden. Sie können beispielsweise IGNORE 1 LINESeine anfängliche Kopfzeile mit Spaltennamen überspringen:

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

Daher können Sie die folgende Anweisung verwenden:

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
quelle
8
Anstatt die erste Zeile zu entfernen, können Sie IGNORE 1 LINESder Abfrage hinzufügen
mb14
Wissen Sie, ob es eine Möglichkeit gibt, den Dateipfad zur CSV-Datei festzulegen?
JasonDavis
Wie kann ich diesen Befehl debuggen, wenn er fehlschlägt? Ich versuche, eine Datei mit diesem Befehl zu laden, aber es tut nichts.
Wie wäre es, wenn ich eine Spalte in CSV ignorieren möchte?
Marci-Mann
Wie gebe ich die Erlaubnis, dass meine lokale CSV-Datei vom MySQL-Server aufgerufen werden kann, der auf aws (rds) ausgeführt wird
rahul
23

Hier ist ein einfaches PHP-Befehlszeilenskript, das genau das tut, was Sie brauchen:

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

?>

Es wird eine Tabelle basierend auf der ersten Zeile erstellt und die verbleibenden Zeilen in diese importiert. Hier ist die Befehlszeilensyntax:

php csv_import.php csv_file.csv table_name
Hawkee
quelle
2
Tolles Drehbuch. Für diejenigen mit doppelt zitierten CSV-Dateien (lesen Sie die meisten Leute) fügen Sie "ENCASED IN" hinzu fields terminated by ','... es funktioniert sogar mit teilweise doppelt zitierten CSVs.
Joel Mellon
3
Ich denke du meinst ENCLOSED BY '\"'... auch viele Leute werden es brauchen, LINES TERMINATED BY '\r\n'wenn sie eine CSV von Windows verwenden. Und schließlich ist es ratsam, den Feldnamen mit Backticks zu entkommen, falls Leerzeichen vorhanden sind:$columns .= "`$column` varchar(250)";
dlo
1
Diese Antwort ist viel besser als die akzeptierte Antwort. Insbesondere erlaubt es, was das OP verlangt, und ich möchte auch: "Die erste Datenzeile wird als Spaltenname verwendet". (Ich würde ein Skript in Python bevorzugen, damit ich PHP nicht installieren muss, aber es sollte nicht schwer sein, es zu portieren.)
LarsH
2
@YumYumYum Können Sie das Problem, das Sie haben, näher erläutern?
Hawkee
Kann ich dir ein Bier kaufen?
Joe
4

Wenn Sie die Möglichkeit haben, phpadmin zu installieren, gibt es einen Importbereich, in dem Sie CSV-Dateien in Ihre Datenbank importieren können. Es gibt sogar ein Kontrollkästchen, mit dem Sie den Header auf die erste Zeile der Datei setzen können, die die Tabellenspaltennamen enthält Die erste Zeile wird Teil der Daten

Jose Ortiz
quelle
Ich bin wirklich überrascht, dass Sie ein Add-On wie phpadmin verwenden müssen, um diese Funktionalität zu erhalten. Vielen Dank für Ihre Antwort
chrisfs
Dies machte gerade meinen Tag
Mark
4

Erstellen Sie zunächst eine Tabelle in der Datenbank mit der gleichen Anzahl von Spalten wie in der CSV-Datei.

Verwenden Sie dann die folgende Abfrage

LOAD DATA INFILE 'D:/Projects/testImport.csv' INTO TABLE cardinfo
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
Mukesh
quelle
Wie wäre es, wenn ich eine Spalte in CSV ignorieren möchte?
Marci-Mann
3

Um Daten aus einer Textdatei oder einer CSV-Datei zu laden, lautet der Befehl

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

Im obigen Befehl muss in meinem Fall nur eine Spalte geladen werden, sodass kein "terminiert von" und "eingeschlossen von" vorhanden ist, sodass ich sie leer gelassen habe. Andernfalls kann der Programmierer das Trennzeichen eingeben. für zB. , (Komma) oder "oder; oder irgendetwas.

** für Leute, die MySQL Version 5 und höher verwenden **

Vor dem Laden der Datei in MySQL muss sichergestellt werden, dass unter der Schleppleine Seite hinzugefügt werden etc/mysql/my.cnf

Befehl my.cnf zu bearbeiten ist

sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  
Rakesh
quelle
3

Wenn Sie mysql als "mysql -u -p --local-infile" starten, funktioniert es einwandfrei

marciomolusco
quelle
2

Ich habe dazu einen Code geschrieben, ich werde ein paar Schnipsel einfügen:

$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

Rufen Sie dann die CSV-Header ab, damit Sie mysql mitteilen können, wie es importiert werden soll (Hinweis: Stellen Sie sicher, dass Ihre mysql-Spalten genau mit den csv-Spalten übereinstimmen):

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

Dann senden Sie Ihre Anfrage an den MySQL-Server:

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
quelle
1

Ich habe einige Zeit damit gerungen. Das Problem liegt nicht darin, wie die Daten geladen werden, sondern wie die Tabelle erstellt wird, um sie zu speichern. Sie müssen eine DDL-Anweisung generieren, um die Tabelle zu erstellen, bevor Sie die Daten importieren.

Besonders schwierig, wenn die Tabelle eine große Anzahl von Spalten enthält.

Hier ist ein Python-Skript, das (fast) den Job macht:

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

Das zu lösende Problem besteht darin, dass der endgültige Feldname und die Datentypdeklaration mit einem Komma abgeschlossen werden und der mySQL-Parser dies nicht toleriert.

Natürlich hat es auch das Problem, dass es für jedes Feld den TEXT-Datentyp verwendet. Wenn die Tabelle mehrere hundert Spalten enthält, wird die Tabelle durch VARCHAR (64) zu groß.

Dies scheint auch bei der maximalen Spaltenanzahl für mySQL zu brechen. Dann ist es Zeit, zu Hive oder HBase zu wechseln, wenn Sie dazu in der Lage sind.

agentv
quelle
1

So habe ich es in Python mit csv und dem MySQL Connector gemacht :

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()

Wichtige Punkte

  • Verwenden Sie vorbereitete Anweisungen für das INSERT
  • Öffnen Sie die Datei.csv 'rb'binär
  • Einige CSV-Dateien müssen möglicherweise angepasst werden , z. B. die skipinitialspaceOption.
  • Wenn 255es nicht breit genug ist, werden beim Einfügen Fehler angezeigt und Sie müssen von vorne beginnen.
  • Passen Sie die Spaltentypen an, z ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • Fügen Sie einen Primärschlüssel hinzu , zALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;
Bob Stein
quelle
0

Importieren Sie CSV-Dateien in die MySQL-Tabelle

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

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

Elangovan
quelle
0

Wie andere bereits erwähnt haben, funktioniert die lokale Infile für Ladedaten einwandfrei. Ich habe das PHP-Skript ausprobiert, das Hawkee gepostet hat, aber es hat bei mir nicht funktioniert. Anstatt es zu debuggen, habe ich Folgendes getan:

1) Kopieren Sie die Kopfzeile der CSV-Datei in eine txt-Datei und bearbeiten Sie sie mit Emacs. Fügen Sie zwischen jedem Feld ein Komma und eine CR ein, um jedes in eine eigene Zeile zu setzen.
2) speichern , die Datei als fieldlist.txt
3) bearbeiten Sie die Datei defns für jedes Feld schließen ( die meisten waren varchar, aber nicht wenige waren int (x). In Tabelle erstellen Tabellennamen (zum Anfang der Datei und) auf dem Ende der Datei. Speichern Sie sie als CreateTable.sql.
4) Starten Sie den MySQL- Client mit Eingaben aus der Createtable.sql-Datei, um die Tabelle zu erstellen.
5) Starten Sie den MySQL-Client Name und CSV-Dateiname. Einfügen in die Datei FieldList.txt. Stellen Sie sicher, dass Sie die 'IGNORE 1 LINES' einfügen, bevor Sie sie in die Feldliste einfügen

Klingt nach viel Arbeit, ist aber mit Emacs einfach .....

Jim Sims
quelle
0

Verwenden Sie die TablePlus-Anwendung: Klicken Sie im rechten Bereich mit der rechten Maustaste auf den Tabellennamen. Wählen Sie Importieren ...> Aus CSV. Wählen Sie CSV-Datei. Überprüfen Sie die Spaltenübereinstimmung und klicken Sie auf Alles importieren!

Milad Hatami
quelle
-3

Ich habe Google-Suche viele Möglichkeiten, um CSV in MySQL zu importieren, "Daten infile laden", MySQL Workbench verwenden, etc.

Wenn ich die Importschaltfläche für MySQL-Workbench verwende, müssen Sie zuerst die leere Tabelle selbst erstellen und jeden Spaltentyp für sich selbst festlegen. Hinweis: Sie müssen am Ende eine ID-Spalte als Primärschlüssel hinzufügen und nicht null und auto_increment. Andernfalls wird die Importschaltfläche später nicht mehr angezeigt. Wenn ich jedoch mit dem Laden einer CSV-Datei beginne, scheint nichts geladen zu sein, was wie ein Fehler aussieht. Ich gebe auf.

Glücklicherweise ist der beste einfache Weg, den ich bisher gefunden habe, Oracle MySQL für Excel zu verwenden. Sie können es von hier herunterladen MySQL für Excel

Dies ist, was Sie tun werden: Öffnen Sie die CSV-Datei in Excel. Suchen Sie auf der Registerkarte Daten die Schaltfläche MySQL für Excel

Wählen Sie alle Daten aus und klicken Sie auf Nach MySQL exportieren. Hinweis zum Festlegen einer ID-Spalte als Primärschlüssel.

Wenn Sie fertig sind, gehen Sie zur MySQL-Workbench, um die Tabelle zu ändern. Der Währungstyp sollte für die reguläre Verwendung dezimal (19,4) für große Mengen dezimal (10,2) sein. Ein anderer Feldtyp kann auf varchar (255) gesetzt werden.

hoogw
quelle