通过命令行将csv导入mysql

问题描述 投票:0回答:9

我正在尝试将一个非常大的 .csv 文件(~4gb)导入到 mysql 中。我正在考虑使用 phpmyadmin,但你的最大上传大小为 2mb。有人告诉我必须使用命令行。

我打算使用这些说明来导入它:http://dev.mysql.com/doc/refman/5.0/en/mysqlimport.html#c5680

将 .csv 表中的第一行设置为 mysql 表中的列名的命令是什么?这个选项可以通过 phpmyadmin 获得,所以它们也必须是 mysql 命令行版本,对吧?请帮我。谢谢。

-拉吉

mysql csv load-data-infile
9个回答
156
投票

尝试这个命令

 load data local infile 'file.csv' into table table
 fields terminated by ','
 enclosed by '"'
 lines terminated by '\n'
 (column1, column2, column3,...)

此处的字段是数据需要驻留在其中的实际表字段。括起来的 和 终止的行是可选的,如果您有用双引号括起来的列(例如 Excel 导出等),则可以提供帮助。

欲了解更多详情,请查看手册

要将第一行设置为表列名称,只需忽略正在读取的行并在命令中添加值即可。


23
投票

试试这个:

mysql -uusername -ppassword --local-infile scrapping -e "LOAD DATA LOCAL INFILE 'CSVname.csv'  INTO TABLE table_name  FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'"

16
投票

你可以做一个

mysqlimport --columns='head -n 1 $yourfile' --ignore-lines=1 dbname $yourfile`

也就是说,如果您的文件以逗号分隔而不是以分号分隔。否则你可能也需要

sed
通过它。


10
投票

您可以简单地通过

导入
mysqlimport --ignore-lines=1 --lines-terminated-by='\n' --fields-terminated-by=',' --fields-enclosed-by='"' --verbose --local -uroot -proot db_name csv_import.csv

注意:Csv 文件名和表名必须相同


6
投票

要使用 mysqlimport 导入带有标题行的 csv,只需添加

--ignore-lines=N

(忽略数据文件的前N行)

您链接的页面中描述了此选项。


1
投票

另一种选择是使用 csvkit 库中的 csvsql 命令。

直接在命令行上使用示例:

csvsql --db mysql:///test --tables yourtable --insert yourfile.csv

这可以直接在命令行上执行,如果您需要对多个文件执行此操作,也可以将其内置到 python 或 shell 脚本中以实现自动化。

csvsql 允许您根据 csv 的结构动态创建数据库表,因此这是一种简单代码方式,可以将 csv 的第一行自动转换为 MySQL 表头。

完整文档和更多示例请参见此处: https://csvkit.readthedocs.io/en/1.0.3/scripts/csvsql.html


0
投票

我知道这说的是命令行,但只是一些快速尝试的小窍门,可能会起作用,如果你有 MySQL 工作台并且 csv 不太大,你可以简单地

  • 从表中选择*
  • 复制整个 CSV
  • 将 csv 粘贴到 Workbench 的查询结果部分
  • 希望一切顺利

我说希望一切顺利,因为这是 MySQL Workbench。你永远不知道什么时候会爆炸


如果您想在远程服务器上执行此操作,您可以这样做

mysql -h<server|ip> -u<username> -p --local-infile bark -e "LOAD DATA LOCAL INFILE '<filename.csv>'  INTO TABLE <table>  FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'"

注意,我没有在

-p
之后输入密码,因为在命令行上输入密码被认为是不好的做法


0
投票

大多数答案都忽略了重要的一点,例如如果您创建了从 Windows 上的 Microsoft Excel 导出的

csv
文件并在 Linux 环境中导入相同的文件,您将得到意想不到的结果。

正确的语法是

load data local infile 'file.csv' into table table fields terminated by ',' enclosed by '"' lines terminated by '\r\n'

这里的区别是

'\r\n'
与简单的
'\n


0
投票

上面的大多数答案都是正确的,并且围绕使用带有

local_infile
的终端上传数据,但这种方法的问题是,如果您拥有共享托管和 phpMyAdmin 实例,那么您可能会陷入以下共享托管提供商无法解决的问题不允许您更改
local_infile
设置。

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile  | OFF   |
+---------------+-------+

为了获得解决方案,我必须在数据库中插入大约 200,000 行。我写了下面的 shell 脚本来完成这项工作。您可以根据您的用例增加或减少

BATCH_SIZE

#!/bin/bash

# MySQL credentials
DB_HOST="host"
DB_USER="db_user"
DB_PASS="db_pass"
DB_NAME="db_name"
TABLE_NAME="table_name"

# Path to the CSV file
CSV_FILE="data.csv"

# Field Separator (comma in this case)
IFS=','

# Batch size
BATCH_SIZE=1000
counter=0
SQL_BATCH="INSERT INTO $TABLE_NAME (sub_category, product_name, product_composition, product_price, product_manufactured, product_desc, product_usp, product_interactions) VALUES "'),"

# Read CSV file line by line
while read -r sub_category product_name product_composition product_price product_manufactured product_desc product_usp product_interactions; do

  # Escape single quotes to prevent SQL syntax errors
  sub_category=$(echo "$sub_category" | sed "s/'/''/g")
  product_name=$(echo "$product_name" | sed "s/'/''/g")
  product_composition=$(echo "$product_composition" | sed "s/'/''/g")
  product_price=$(echo "$product_price" | sed "s/'/''/g")
  product_manufactured=$(echo "$product_manufactured" | sed "s/'/''/g")
  product_desc=$(echo "$product_desc" | sed "s/'/''/g")
  product_usp=$(echo "$product_usp" | sed "s/'/''/g")
  product_interactions=$(echo "$product_interactions" | sed "s/'/''/g")

  # Append the current row values to the SQL batch
  SQL_BATCH="$SQL_BATCH ('$sub_category', '$product_name', '$product_composition', '$product_price', '$product_manufactured', '$product_desc', '$product_usp', '$product_interactions'),"

  # Increment the counter
  ((counter++))

  # If we have reached the batch size, execute the SQL
  if [[ $counter -eq $BATCH_SIZE ]]; then
    # Remove the last comma and add a semicolon to complete the SQL statement
    SQL_BATCH="${SQL_BATCH%,};"
    
    # Execute the batch insert
    mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" -D "$DB_NAME" -e "$SQL_BATCH"
    
    # Reset the batch and counter
    SQL_BATCH="INSERT INTO $TABLE_NAME (sub_category, product_name, product_composition, product_price, product_manufactured, product_desc, product_usp, product_interactions) VALUES "
    counter=0
  fi

done < "$CSV_FILE"

# Execute the remaining records if there are any
if [[ $counter -gt 0 ]]; then
  # Remove the last comma and add a semicolon
  SQL_BATCH="${SQL_BATCH%,};"
  
  # Execute the remaining batch
  mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" -D "$DB_NAME" -e "$SQL_BATCH"
fi

echo "Data import complete."

在数据量较大的情况下,此解决方案可能需要一些时间,但可以完成工作。

© www.soinside.com 2019 - 2024. All rights reserved.