【问题标题】:How to import a CSV file into a MySQL table如何将 CSV 文件导入 MySQL 表
【发布时间】:2012-06-20 02:59:53
【问题描述】:

如何将 CSV 文件导入 MySQL 表?我想将第一行数据用作列名。

我阅读了How do I import CSV file into a MySQL table?,但唯一的答案是使用 GUI 而不是 shell?

【问题讨论】:

  • 甚至 GUI 解决方案也不会从 csv 中获取列名...您需要在导入之前创建整个表-
  • 问题在这里已经有了答案stackoverflow.com/questions/3635166/…
  • 在您链接到的问题上接受的答案是使用 GUI。您所引用的答案是昨天提供的,而这个问题(答案)来自 2012 年。
  • 或使用来源问题中提到的mysqlimport
  • 这是 stackoverflow.com/questions/3635166/… 的副本,即使您不喜欢 GUI。您可以发布赏金以寻求更好的问题。在这种情况下,无论如何,在您提出这个问题大约 1 年后才提供基于非 GUI 的答案。我当天没有票,但明天会回来。

标签: mysql csv import load-data-infile database-table


【解决方案1】:

您可以直接将 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)

继续阅读:Import CSV file directly into MySQL

编辑

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


EDIT-2

来自 MySQL 文档on LOAD DATA syntax

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)

【讨论】:

  • 您可以将IGNORE 1 LINES 添加到查询中,而不是删除第一行
  • 你知道有没有办法将文件路径设置为csv文件?
  • 该命令失败时如何调试?我正在尝试使用此命令加载文件,但它什么也没做。
  • 如果我想忽略 csv 中的一列呢?
  • 如何允许我的 csv 本地文件被运行在 aws (rds) 上的 mysql 服务器访问
【解决方案2】:

这是一个简单的 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

【讨论】:

  • 很棒的脚本。 对于那些有双引号 CSV 文件的人(大多数人都读)添加 `ENCASED IN '\"'` 到 fields terminated by ',' ...它甚至可以与部分双引号 CSV。
  • 我认为您的意思是ENCLOSED BY '\"'... 另外,如果使用 Windows 中的 CSV,很多人将需要 LINES TERMINATED BY '\r\n'。最后,用反引号转义字段名称是明智的,以防有空格:$columns .= "`$column` varchar(250)";
  • 这个答案比公认的答案要好得多。特别是它允许 OP 要求的内容,我也想要:“第一行数据用作列名”。 (我更喜欢 Python 中的脚本,所以我不必安装 PHP,但移植它应该不难。)
  • @YumYumYum 你能详细说明你遇到的问题吗?
  • 我可以请你喝啤酒吗?
【解决方案3】:

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

【讨论】:

  • 我真的很惊讶你必须使用像 phpadmin 这样的插件来获得这个功能,谢谢你的回答
  • 这让我很开心
【解决方案4】:

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

然后使用以下查询

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

【讨论】:

  • 如果我想忽略 csv 中的一列呢?
【解决方案5】:

如果你以“mysql -u -p --local-infile”启动mysql,它会正常工作

【讨论】:

    【解决方案6】:

    要从文本文件或 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  
    

    【讨论】:

      【解决方案7】:

      我写了一些代码来做这个,我会放几个sn-ps:

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

      【讨论】:

        【解决方案8】:

        我为此苦苦挣扎了一段时间。问题不在于如何加载数据,而在于如何构造表来保存它。在导入数据之前,您必须生成一个 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 的时候了。

        【讨论】:

          【解决方案9】:

          这是我在 Python 中使用 csvMySQL Connector 的方法:

          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 文件可能需要tweaking,例如skipinitialspace 选项。
          • 如果 255 不够宽,您将在 INSERT 上遇到错误,并且必须重新开始。
          • 调整列类型,例如ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
          • 添加primary key,例如ALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;

          【讨论】:

            【解决方案10】:

            将 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

            【讨论】:

              【解决方案11】:

              使用 TablePlus 应用程序: 右键单击右侧面板中的表名 选择导入... > 从 CSV 选择 CSV 文件 查看列匹配并点击导入 全部完成!

              【讨论】:

                【解决方案12】:

                正如其他人所提到的,加载数据本地 infile 工作得很好。我尝试了 Hawkee 发布的 php 脚本,但它对我不起作用。而不是调试它,这就是我所做的:

                1) 将 CSV 文件的标题行复制/粘贴到 txt 文件中,并使用 Emacs 进行编辑。在每个字段之间添加逗号和 CR 以使每个字段占一行。
                2) 将该文件另存为 FieldList.txt。
                3) 编辑文件以包含每个字段的定义(大多数是 varchar,但也有不少是 int(x)。添加 create table *tablename*(到文件的开头和)到文件的末尾。保存它作为 CreateTable.sql.
                4) 使用 Createtable.sql 文件中的输入启动 mysql 客户端以创建表。
                5)启动mysql客户端,复制/粘贴大部分'LOAD DATA INFILE'命令,替换我的表名和csv文件名。粘贴到 FieldList.txt 文件中。在粘贴到字段列表之前,请务必包含“IGNORE 1 LINES”。

                听起来工作量很大,但使用 Emacs 很容易......

                【讨论】:

                  【解决方案13】:

                  我在google上搜索过很多将csv导入mysql的方法,包括“load data infile”、使用mysql workbench等。

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

                  幸运的是,到目前为止我发现的最简单的方法是使用 Oracle 的 mysql for excel。你可以从这里下载它mysql for excel

                  这就是你要做的: 在 excel 中打开 csv 文件,在“数据”选项卡中,找到 mysql for excel 按钮

                  选择所有数据,点击导出到mysql。 请注意将 ID 列设置为主键。

                  完成后,去mysql工作台修改表, 例如货币类型应为十进制(19,4),用于大额十进制(10,2),用于常规使用。 其他字段类型可以设置为 varchar(255)。

                  【讨论】:

                    猜你喜欢
                    • 2011-04-07
                    • 2016-06-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-05-15
                    • 1970-01-01
                    相关资源
                    最近更新 更多