将CSV导入mysql表


96

将csv文件上传到mysql表的最佳/最快方法是什么?我想将第一行数据用作列名。

发现了这一点:

如何将CSV文件导入MySQL表

但是唯一的答案是使用GUI而不是Shell?


3
甚至GUI解决方案也不会从csv中获取列名...您需要在导入之前创建整个表
Dominique 2014年

这个问题已经在这里有一个答案stackoverflow.com/questions/3635166/...
大卫·

您链接到的问题所接受的答案是使用GUI。您引用的答案是昨天提供的,而该问题的答案是2012
。– lcm

Answers:


147

您可以直接将MYSQL链接到该文件并使用以下SQL语法上传信息,而不必编写脚本从CSV文件中提取信息。

要将Excel文件导入MySQL,请先将其导出为CSV文件。从生成的CSV文件中删除CSV标头,以及Excel可能放在该CSV文件末尾的空数据。

然后可以通过运行以下命令将其导入到MySQL表中:

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

阅读时:将CSV文件直接导入MySQL

编辑

对于您的情况,您需要首先编写一个解释器,以查找第一行并将其分配为列名。


编辑2

从MySQL文档了解LOAD DATA语法

IGNORE number LINES选项可用于忽略文件开头的行。例如,您可以IGNORE 1 LINES用来跳过包含列名的初始标题行:

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

因此,您可以使用以下语句:

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
除了删除第一行,您还可以添加IGNORE 1 LINES到查询
mb14 2014年

您是否知道是否可以将文件路径设置为csv文件?
JasonDavis

该命令失败时如何调试?我正在尝试使用此命令加载文件,但它无能为力。

如果我想忽略csv中的列怎么办?
Marci-man

如何授予在aws(rds)上运行的mysql服务器访问我的csv本地文件的权限
rahul

24

这是一个简单的PHP命令行脚本,可以满足您的需要:

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

?>

它将基于第一行创建一个表,并将剩余的行导入其中。这是命令行语法:

php csv_import.php csv_file.csv table_name

2
很棒的脚本。对于那些带有双引号CSV文件(大多数人)的人,在其上添加`ENCASED IN'\“'` fields terminated by ','甚至可以使用部分双引号CSV。–
Joel Mellon

3
我认为您的意思是ENCLOSED BY '\"'...而且,LINES TERMINATED BY '\r\n'如果使用Windows的CSV ,则很多人都需要。最后,在有空格的情况下,使用反引号将字段名称转义是明智的:$columns .= "`$column` varchar(250)";
dlo 2013年

1
这个答案比接受的答案好得多。特别是,它允许OP要求的内容,我还希望:“数据的第一行用作列名”。(我希望使用Python中的脚本,因此不必安装PHP,但移植起来也不难。)
LarsH 2015年

2
@YumYumYum您能详细说明您遇到的问题吗?
Hawkee '16

我可以给你买啤酒吗?

4

如果您具有安装phpadmin的能力,则有一个import区域,您可以在其中将csv文件导入数据库,甚至还有一个复选框将标题设置为包含表列名称的文件的第一行(如果未选中,则第一行将成为数据的一部分


我真的很惊讶您必须使用像phpadmin这样的附加组件才能获得此功能,谢谢您的回答
chrisfs 2015年

这就是我的一天
马克

4

首先在数据库中创建一个与csv文件中的列数相同的表。

然后使用以下查询

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

如果我想忽略csv中的列怎么办?
Marci-man

3

要从文本文件或csv文件加载数据,命令为

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

在上面的命令中,在我的情况下,只有一列要加载,因此没有“终止于”和“封闭于”,因此我将其保留为空,否则程序员可以输入分隔字符。例如。,(逗号)或“或;或其他任何东西。

**适用于使用mysql版本5及更高版本的人**

在将文件加载到mysql中之前,必须确保在侧面添加了以下拖曳行 etc/mysql/my.cnf

编辑my.cnf命令是

sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  


2

我写了一些代码来做到这一点,我将添加一些片段:

$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

然后获取CSV标头,以便您可以告诉mysql如何导入(请注意:确保mysql列与csv列完全匹配):

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

然后将您的查询发送到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

我为此花了一段时间。问题不在于如何加载数据,而在于如何构造表来保存数据。在导入数据之前,您必须生成DDL语句来构建表。

如果表具有大量列,则特别困难。

这是(几乎)完成此工作的python脚本:

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

它剩下要解决的问题是最终字段名和数据类型声明以逗号终止,而mySQL解析器将无法接受。

当然,它还具有以下问题:它为每个字段使用TEXT数据类型。如果表有几百列,则VARCHAR(64)将使表太大。

这似乎也打破了mySQL的最大列数。如果可以的话,那就是时候该迁移到Hive或HBase了。


1

这是我使用csvMySQL Connector在Python中完成的操作:

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

关键点

  • 对INSERT使用准备好的语句
  • 'rb'二进制打开file.csv
  • 某些CSV文件可能需要调整,例如skipinitialspace选项。
  • 如果255不够宽,您将在INSERT上收到错误,必须重新开始。
  • 调整列类型,例如 ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • 添加一个主键,例如ALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;

0

将CSV文件导入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

访问次数:http : //www.webslessons.com/2014/02/import-csv-files-using-php-and-mysql.html


0

正如其他人提到的那样,加载数据本地infile可以正常工作。我尝试了Hawkee发布的php脚本,但没有为我工作。而不是调试它,这是我所做的:

1)将CSV文件的标题行复制/粘贴到txt文件中,然后使用emacs进行编辑。在每个字段之间添加逗号和CR,以使每行都单独显示。
2)保存该文件作为FieldList.txt
3)编辑的文件,以包含每个字段defns(大多数是VARCHAR,但相当多的人INT(x)的添加创建表的表名(该文件并开始时)至将其保存为CreateTable.sql
4)使用Createtable.sql文件中的输入启动mysql客户端以创建表
5)启动mysql客户端,复制/粘贴大部分“ LOAD DATA INFILE”命令以替换我的表名称和csv文件名。粘贴在FieldList.txt文件中。粘贴到字段列表之前,请确保包括“ IGNORE 1 LINES”

听起来工作量很大,但是使用emacs可以轻松完成.....


0

使用TablePlus应用程序:在右面板上右键单击表名称,选择Import ...> From CSV选择CSV文件,查看列匹配并单击Import All done!


-3

我有谷歌搜索将csv导入到mysql的许多方法,包括“在infile中加载数据”,使用mysql工作台等。

当我使用mysql workbench导入按钮时,首先需要自己创建一个空表,并自行设置每个列的类型。注意:您必须在末尾添加ID列作为主键,而不是null和auto_increment,否则,导入按钮稍后将不可见。但是,当我开始加载CSV文件时,没有加载任何内容,似乎是一个错误。我放弃。

幸运的是,到目前为止,我发现最好的简便方法是将Oracle的mysql用于excel。您可以从这里下载mysql for excel

这就是您要执行的操作:在Excel中的“数据”选项卡上打开csv文件,找到excel的mysql按钮

选择所有数据,单击Export to mysql。请注意将ID列设置为主键。

完成后,转到mysql workbench更改表,例如,对于常规使用的大量十进制(10,2),货币类型应为小数(19,4)。其他字段类型可以设置为varchar(255)。

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.