如何将CSV文件导入到MySQL表中?


306

我有一个来自客户端的非标准化事件日志CSV,我试图将其加载到MySQL表中,以便可以将其重构为合理的格式。我创建了一个名为“ CSVImport”的表,该表的CSV文件的每一列都有一个字段。CSV包含99列,因此这本身就是一项艰巨的任务:

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

该表上没有任何约束,并且所有字段都包含VARCHAR(256)值,但包含计数(以INT表示),是/否(以BIT表示),价格(以DECIMAL表示)和文本框()的列除外。由TEXT表示)。

我试图将数据加载到文件中:

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               | 
...

整个桌子上满是NULL

我认为问题在于文本内容包含多行,而MySQL正在解析文件,好像每一行都对应于一个databazse行。我可以毫无问题地将文件加载到OpenOffice中。

clientdata.csv文件包含2593行和570条记录。第一行包含列名。我认为它是用逗号分隔的,并且文本显然是用双引号分隔的。

更新:

如有疑问,请阅读手册:http : //dev.mysql.com/doc/refman/5.0/en/load-data.html

我在LOAD DATA声明中添加了一些信息,即OpenOffice足够智能,可以推断出,现在它可以加载正确数量的记录:

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;

但是仍然有很多完整的NULL记录,而且似乎都没有在正确的位置加载任何数据。


17
而且,如果您使用的是OSX,Sequel Pro拥有出色的导入工具,并且是免费的;-)
Merrick 2013年

41
令我惊讶的是,原始海报比其他任何人都可以更好地回答他自己的问题...我不知道为什么当现有的SQL命令可以是编程的而不是UI 时,为什么这么多人愿意提供软件建议基于。我对其他人一无所知,但是对我而言,编程的方式意味着我可以设置脚本以在时间戳上自动导入文件,而基于UI的纯粹是手动的。
克里斯·西里菲斯

@ChrisCirefice:我认为公认的答案很好地说明了这一点。他需要手动创建“加载数据”命令的帮助,图形程序可以提供帮助。一旦图形程序创建了“加载数据”命令,他就可以以编程方式重用它。
AlexC 2014年

@Merrick这对osx
起到了作用

我编写了详尽的教程,将csv数据Excel中语法生成器工具一起加载到mysql
mysql_user

Answers:


133

您问题的核心似乎是将CSV文件中的列与表中的列进行匹配。

许多图形化的mySQL客户端都有很好的导入对话框。

我最喜欢这份工作的是基于Windows的HeidiSQL。它为您提供了图形界面来构建LOAD DATA命令。您可以稍后以编程方式重用它。

导入文本文件

屏幕截图:“导入文本文件”对话框

要打开“导入文本文件”对话框,请转到Tools > Import CSV file

在此处输入图片说明


25
对于Mac OSX,请使用Sequel Pro。
Agi Hammerthief 2014年

3
我只是尝试过,它需要我首先创建表...而不是使用列名。
Dominique 2014年

3
您必须先选择一张桌子,然后才能继续...而且由于不必
Dominique 2014年

3
请注意,在Linux中,HeidiSQL在Wine下可以很好地工作。
AlejandroVD

1
@保罗非常一点的回答是,GUI工具可以使匹配进口列于表列更容易。
佩卡

191

使用mysqlimport将表加载到数据库中:

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

我在http://chriseiffel.com/everything-linux/how-to-import-a-large-csv-file-to-mysql/找到了

要使定界符成为制表符,请使用 --fields-terminated-by='\t'


6
mysqlimportLOAD DATA INFILE...在幕后使用,因此几乎是同一回事。
MladenJablanović2014年

8
与之相同LOAD DATA INFILE,您需要先创建一个表才能使用mysqlimport
Marcus Downing 2015年

@MladenJablanović,绝对不是同一回事。尝试导入10亿行。您会惊讶于它在性能方面产生巨大的变化
ninjabber

@ninjabber文档 mysqlimport客户端提供了一个到LOAD DATA INFILE的命令行界面,因此从理论上讲,它不可能提供任何性能优势LOAD DATA INFILE
MladenJablanović'16

1
也需要--fields-optionally-enclosed-by=\"和--fields-escaped-by = \`
chaintng

80

我已导入200多行的最简单方法是在phpmyadmin sql窗口中的命令下方

我有一个简单的国家表,其中有两列CountryId,CountryName

这是.csv数据CSV文件

这是命令:

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

请记住一件事,不要出现在第二栏中,否则您的导入将停止


1
如果是TSV文件,则为','->'\ t','“'->'',如果没有标题则删除最后一行(希望搜索搜寻器为此索引)
2014年

16
如果是本地文件,则可能需要LOAD DATA LOCAL INFILE。如果抛出错误1148“不允许使用的命令”,则可以通过在命令行上运行mysql来启用它--local-infile
Big McLargeHuge 2015年

我收到错误消息:错误1045(28000):用户'user'@'%'的访问被拒绝(使用密码:是)
ARUNBALAN NV

您必须从管理面板向用户授予所有访问权限,然后尝试导入脚本。
DareDevil

1
我收到此错误:MySQL服务器正在使用--secure-file-priv选项运行,因此它无法执行该语句
Agniswar Bakshi

66

我知道这个问题很老,但我想分享一下

我用这个方法导入100K以上的记录(〜5MB的)0.046sec

这是您的操作方式:

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

如果您有多个字段,则包括最后一行非常重要,即通常它会跳过最后一个字段(MySQL 5.6.17)

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

然后,假设您将第一行作为字段的标题,则可能还希望包括此行

IGNORE 1 ROWS

如果您的文件有标题行,这就是它的样子。

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

我导入了16k行和48列。谢谢你,哥们。
Renjith VR

这是最好的解决方案。对于任何想知道它有多快的人:我在14秒内在一个价格为20美元/月的AWS Lightsail实例上,使用板载MySQL服务器(不是高性能RDS)导入了320万行。太棒了!
master_gracey

在此行中,(field_1,field_2 , field_3);它是否引用.csv文件或表中的列列表?即,这些字段是什么?
tera_789 '18

@ tera_789在您的csv文件中可能与您的表匹配的文件
Fahad

必须遵循数据格式。示例(针对我的情况)<pre>名字,姓氏,登记,电话号码,电子邮件,姓名,姓氏,2018年12月5日,54545,faiz @ gmail.com,姓名1,姓氏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可以处理CSV导入。步骤如下:

  1. 准备CSV文件,使其字段与MySQL表字段的顺序相同。

  2. 从CSV中删除标题行(如果有的话),以便仅数据在文件中。

  3. 转到phpMyAdmin界面。

  4. 在左侧菜单中选择表格。

  5. 点击顶部的导入按钮。

  6. 浏览到CSV文件。

  7. 选择选项“使用LOAD DATA的CSV”。

  8. 在“终止于”的字段中输入“,”。

  9. 以与数据库表中相同的顺序输入列名。

  10. 单击执行按钮,您就完成了。

这是我准备供将来使用的注释,如果有人可以从中受益,请在此处分享。


这既好又简单。我更喜欢通过SQL创建表和列(因此我跳过了步骤9),并通过导入CSV插入数据。不要忘记NULL在CSV中设置任何自动递增的字段/列。
银色

请注意,当将西里尔字符包含到CSV文件中时,无论您告诉它使用utf-8,phpMyAdmin都会失败。
Fran Marzoa '16

如果要导入大型CSV文件,请不要忘记更改导入大小。顺便说一句,对于大型CSV文件,它不是一个不错的选择。
Avi

这需要先将.csv文件下载到Web客户端,因为您无法浏览到本地csv文件。
mckenzm

是的,您可以,您需要选中标记为“本地关键字”的复选框,然后才能使用本地csv文件
chrisfs

12

您可以通过列出LOAD DATA语句中的列来解决此问题。从手册

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

...因此,您需要按其在csv文件中出现的顺序列出99列。


8

试试这个,对我有用

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

IGNORE 1 ROWS在这里忽略包含字段名称的第一行。请注意,对于文件名,您必须键入文件的绝对路径。


这是最好的答案。当一个SQL命令可以执行操作时,为什么还要使用其他工具?
sdgfsdh

当您尝试将文件加载到服务器上运行的mysql中时,您知道如何使此工作正常吗?它要求我拒绝访问该文件(密码)。在哪里输入csv文件位置的密码?
Baktaawar

7

mysql命令行在导入时容易出现太多问题。这是您的操作方式:

  • 使用excel编辑标题名称以没有空格
  • 另存为.csv
  • 使用免费的Navicat Lite SQL浏览器导入并自动创建新表(为其命名)
  • 打开新表,为ID插入主自动编号列
  • 根据需要更改列的类型。
  • 完成!

5

如果您使用的是MySQL Workbench(当前为6.3版),则可以通过以下方式进行操作:

  1. 右键单击“表”;
  2. 选择表数据导入向导;
  3. 选择您的csv文件并按照说明进行操作(也可以使用JSON);好处是,您可以基于要导入的csv文件创建新表或将数据加载到现有表中

在此处输入图片说明


+1。我之所以使用它,是因为mysql一直在给我错误LOAD DATA INFILEmysqlimport(“此版本的mysql不支持此”)
clmno

这种方法有效,但是有点慢。我以为使用此功能将建立一个庞大的INSERT查询并尝试一次完成所有操作,但是这样做似乎实际上实际上INSERT每行运行一次。
DaveTheMinion

4

我看到一些奇怪的东西。您要为ESCAPING使用与ENCLOSING相同的字符。因此,引擎发现“'”时不知道该怎么办,我认为这就是为什么似乎没有正确的地方的原因。我认为,如果删除ESCAPING行,应该运行得很好。

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

除非您分析(手动,直观地...)您的CSV并找到哪个字符用于转义。有时是“ \”。但是,如果您没有它,请不要使用它。


3

另一个解决方案是使用令人赞叹的csvkit套件中的csvsql工具。

用法示例:

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

该工具可以自动推断数据类型(默认行为),创建表并将数据插入到创建的表中。--overwrite选项可以用于删除表(如果已存在)。--insertoption —从文件填充表。

安装套件

pip install csvkit

先决条件: python-devlibmysqlclient-devMySQL-python

apt-get install python-dev libmysqlclient-dev
pip install MySQL-python

3

如何将CSV文件导入到SQL表

示例文件:Overseas_trade_index数据CSV文件

脚步:

  1. 需要为创建表overseas_trade_index

  2. 需要创建与csv文件相关的列。

    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. 需要在终端连接mysql数据库。

    =>show databases;
    =>use database;
    =>show tables;
  4. 请输入此命令以将csv数据导入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. 在sqldatabase上找到此海外贸易指数数据:

    select * from trade_index;

2

如果您使用的是装有Excel电子表格的Windows计算机,则Excel的新mySql插件会非常出色。Oracle的员工确实在该软件上做得很好。您可以直接从Excel建立数据库连接。该插件将分析您的数据,并以与数据一致的格式为您设置表格。我有一些要转换的巨型CSV文件数据。此工具可节省大量时间。

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

您可以从Excel中进行更新,这些更新将在线填充到数据库中。这与在超便宜的GoDaddy共享主机上创建的mySql文件非常兼容。(请注意,在GoDaddy创建表时,必须选择一些非标准设置才能启用数据库的非现场访问...)

使用此插件,您可以在XL电子表格和在线mySql数据存储之间进行纯粹的交互。


2

我使用mysql workbench来完成相同的工作。

  1. 创建新架构
  2. 打开新创建的架构
  3. 右键单击“表”,然后选择“表数据导入向导”
  4. 提供csv文件路径和表名,最后配置您的列类型,因为向导会根据其值设置默认列类型。

注意:使用“ tail -f [mysqlworkbenchpath] /log/wb*.log”,查看mysql工作台的日志文件是否存在任何错误。


非常感谢您的回答-是MySQL的新手,我对此并不了解-它为CSV提供了帮助。现在,我还需要从Access导入10个表-您认为最简单的方法是将这些表导出到Excel中,从Excel导出到CSV,然后使用这些步骤吗?
内奥米

我发现此方法不能导入所有行:(在5,342行中,它只为我导入了2,485行。为什么呢?
Naomi

嗨,娜奥米,如果您查看mysqlworkbench日志,它将向您显示为什么它停止导入数据。您的数据库和CSV文件中可能有一些空值或不匹配类型。但是我强烈建议您遵循Juan的回答(紧随我之后)。他的解决方案比我更好,更干净。
Mehdi

1

这是示例excel文件的屏幕截图:

在此处输入图片说明

另存为,然后选择.csv。

如果使用记事本++或任何其他记事本打开,则将显示如下所示的.csv数据屏幕截图。

在此处输入图片说明

确保删除标题,并在.csv中像mysql表中那样进行列对齐。用您的文件夹名称替换folder_name

将数据本地文件
'D:/folder_name/myfilename.csv'装入表邮件字段,以','(fname,lname,email,phone)终止;

如果数据很大,您可以喝咖啡并装入!

那就是您所需要的。



0

PHP查询导入CSV文件到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));
   }

**样本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

0

更改服务器名,用户名,密码,dbname,文件路径,表名以及要插入的数据库中的字段

<?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>'
       }
    ?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.