【发布时间】:2012-01-22 06:21:22
【问题描述】:
有没有办法将多个 csv 文件同时导入 MySQL 数据库?某种批量导入?
我在运行 MAMP 服务器的 Mac OSX 上。
我有 185 个 csv 文件需要导入到 MySQL 表中。我可以使用 phpMyAdmin 的导入选项卡单独导入它们,但这需要很长时间。有谁知道有没有更好的方法?
【问题讨论】:
标签: mysql import phpmyadmin
有没有办法将多个 csv 文件同时导入 MySQL 数据库?某种批量导入?
我在运行 MAMP 服务器的 Mac OSX 上。
我有 185 个 csv 文件需要导入到 MySQL 表中。我可以使用 phpMyAdmin 的导入选项卡单独导入它们,但这需要很长时间。有谁知道有没有更好的方法?
【问题讨论】:
标签: mysql import phpmyadmin
使用这样的 shell 脚本:
#!/usr/bin/env bash
cd yourdirectory
for f in *.csv
do
mysql -e "USE yourDatabase LOAD DATA LOCAL INFILE '"$f"'INTO TABLE yourtable"
done
【讨论】:
有一个 PHP 小脚本适合你:
#!/usr/bin/php
<?
mysql_connect('localhost','root','root'); // MAMP defaults
mysql_select_db('yourdatabase');
$files = glob('*.csv');
foreach($files as $file){
mysql_query("LOAD DATA INFILE '".$file."' INTO TABLE yourtable");
}
有关适合您文档的LOAD DATA INFILE 选项,请参阅 MySQL 手册。
【讨论】:
您可以使用 shell 脚本来遍历文件(假设它们在当前目录中):
#!/bin/bash
for f in *.csv
do
mysql -e "load data infile '"$f"' into table my_table" -u username --password=your_password my_database
done
【讨论】:
我修改了 Tom 的脚本以解决一些面临的问题
#!/bin/bash
for f in *.csv
do
mysql -e "load data local infile '"$f"' into table myTable fields TERMINATED BY ',' LINES TERMINATED BY '\n'" -u myUser--password=myPassword fmeter --local-infile
done
load data local infile 而不是 load data infile :[要加载的文件是 mysql 服务器的本地文件]--local-infile 在客户端启用本地数据加载模式。【讨论】:
对于 windows 用户使用此批次
echo off
setlocal enabledelayedexpansion
FOR %%f IN ("*.csv") DO (
set old=%%~dpnxf
set new=!old:\=\\!
mysql -e "load data local infile '"!new!"' IGNORE into table email_us.business COLUMNS TERMINATED BY ','" -u root
echo %%~nxf DONE
)
d 用于驱动器号,p 用于路径
到文件,n 为文件名,x 为扩展名,f 是文件变量步骤: - 将该批处理文件放在所有多个 csv 文件存在的目录中,并将其命名为 something.bat - 以管理员身份运行 cmd.exe 并调用 something.bat 文件并享受导入...
【讨论】:
在 python 中,你可以使用d6tstack,这让这很简单
import d6tstack
import glob
c = d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv'))
c.to_mysql_combine('mysql+mysqlconnector://usr:pwd@localhost/db', 'tablename')
它还处理data schema changes,创建表并允许您预处理数据。
【讨论】:
c.to_sql(name='inequity', con=engine, if_exists='append', index=False, chunksize=200)
我对很多 CSV 文件有相同的任务,并通过 CSV 创建一个表,所以这是我在 XAMP 下本地使用的脚本。
<?php
ini_set('display_errors',1);
echo '### Begin Importation<br>';
$mysqli = new mysqli(
"localhost",
"root",
"",
"mydatabase",
3306
);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$files = glob('C:\\xampp\\mysql\\data\\mev2\\*.csv');
foreach($files as $file){
//clean names if needed
$filename = explode('\\',$file);
$filename2clean = str_replace('.csv','', $filename[5]);//because my file is under 5 folders on my PC
$n = strtolower(str_replace('fileprefix_','', filename2clean));
echo '<br>Create table <b>'.$n.'</b><hr>';
$sql = "CREATE TABLE IF NOT EXISTS `mydatabase`.`".$n."` (`email` varchar(60), `lastname` varchar(60), `firstname` varchar(60), `country` varchar(19)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;";
if (!($stmt = $mysqli->query($sql))) {
echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
};
echo '<br>Import data from <b>'.$n.'</b><hr>';
$sql = "LOAD DATA INFILE '".basename($file)."' INTO TABLE `mydatabase`.`".$n."`
FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\r'
IGNORE 1 LINES";
if (!($stmt = $mysqli->query($sql))) {
echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error;
};
}
echo '### Import finished !<br>';
【讨论】:
@hlosukwakha 你想使用mysqlimport。
这将搜索一个名为该文件的表。
使用mysqlimport -help找到正确的参数,但它们与mysql基本相同
【讨论】:
使用以下 shell 脚本:
for file in /directory/*.csv
do
echo "Importing file $file"
chown mysql $file
mysql Fortinet -u user -p'password' <<EOF
LOAD DATA LOCAL INFILE '$file'
IGNORE
INTO TABLE tablename
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES;
EOF
echo "Completed importing '"$file"' "
done
【讨论】:
我像 @citynorman 一样使用 Python 和 d6tstack,但因为我在 200 个 CSV 文件中有 2400 万行,这种方法正在扼杀我的开发数据库服务器。
这种方法只需 2 或 3 行代码即可为您提供大量控制和性能。它将 2400 万行提取到一个五索引列的 MySQL 表中,并在大约 2 分钟内添加了数据清理。 MySQL Workbench 上的 csv 导入工具需要几天时间才能完成相同的操作。
这是我所做的工作:
import pandas as pd
import importlib
import d6tstack.combine_csv as d6tc
import d6tstack
import glob
import pymysql # This approach also supports other MySQL connectors
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://usr:pass@host:3306/db")
# For testing just pull in one or two csv files - and then take all
# My data had a ; semicolon separator, so change this to your use case if needed
df = d6tc.CombinerCSV(glob.glob('C:/Users/user/Downloads/csvfiles/*.csv'), sep=';').to_pandas()
# Remove Filepath and Filename
df.drop(columns=["filepath","filename"],inplace=True, axis=1)
# I created Indexes in my database file during testing, so this line
# makes sure there are no null index values in the CSVs
df = df[df['country'].notna()]
# chunksize throttles your database updates so as not to overwhelm any buffers
# NEVER use "if_exists=replace", unless you want to blank your table 100%
df.to_sql(name='table', con=engine, if_exists='append', index=False, chunksize=200)
【讨论】: