Nhập CSV vào bảng mysql


96

Cách tốt nhất / nhanh nhất để tải tệp csv lên bảng mysql là gì? Tôi muốn hàng dữ liệu đầu tiên được sử dụng làm tên cột.

Tìm thấy cái này:

Cách nhập tệp CSV vào bảng MySQL

Nhưng câu trả lời duy nhất là sử dụng GUI chứ không phải shell?


3
Và ngay cả những giải pháp GUI không lấy tên cột từ csv ... bạn cần để tạo ra toàn bộ bảng trước khi importing-
Dominique

Câu hỏi đã có câu trả lời ở đây stackoverflow.com/questions/3635166/…
David

câu trả lời được chấp nhận cho câu hỏi bạn đang liên kết là sử dụng GUI. Câu trả lời bạn là tài liệu tham khảo được cung cấp ngày hôm qua trong khi câu hỏi này (câu trả lời) là từ năm 2012.
lcm

Câu trả lời:


147

Thay vì viết một tập lệnh để lấy thông tin từ tệp CSV, bạn có thể liên kết MYSQL trực tiếp với nó và tải lên thông tin bằng cú pháp SQL sau.

Để nhập tệp Excel vào MySQL, trước tiên hãy xuất tệp đó dưới dạng tệp CSV. Xóa tiêu đề CSV khỏi tệp CSV đã tạo cùng với dữ liệu trống mà Excel có thể đã đặt ở cuối tệp CSV.

Sau đó, bạn có thể nhập nó vào một bảng MySQL bằng cách chạy:

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

như đã đọc: Nhập tệp CSV trực tiếp vào MySQL

BIÊN TẬP

Đối với trường hợp của bạn, trước tiên bạn sẽ cần viết một trình thông dịch để tìm hàng đầu tiên và gán chúng làm tên cột.


EDIT-2

Từ tài liệu MySQL về LOAD DATAcú pháp :

Các IGNORE number LINEStùy chọn có thể được sử dụng để bỏ qua dòng vào lúc bắt đầu của tập tin. Ví dụ: bạn có thể sử dụng IGNORE 1 LINESđể bỏ qua dòng tiêu đề ban đầu chứa tên cột:

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

Do đó, bạn có thể sử dụng câu lệnh sau:

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
Thay vì loại bỏ dòng đầu tiên bạn có thể thêm IGNORE 1 LINESvào truy vấn
mb14

Bạn không biết có cách nào để đặt đường dẫn tệp đến tệp csv không?
JasonDavis

Làm thế nào để gỡ lỗi lệnh này khi nó không thành công? tôi đang cố gắng tải một tệp bằng lệnh này nhưng nó không có tác dụng gì.

Còn nếu tôi muốn bỏ qua một cột trong csv thì sao?
Marci-man

làm thế nào để cho phép cho csv của tôi tập tin địa phương để được truy cập bởi máy chủ mysql chạy trên AWS (RDS)
Rahul

24

Đây là một tập lệnh dòng lệnh PHP đơn giản sẽ thực hiện những gì bạn cần:

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

?>

Nó sẽ tạo một bảng dựa trên hàng đầu tiên và nhập các hàng còn lại vào đó. Đây là cú pháp dòng lệnh:

php csv_import.php csv_file.csv table_name

2
Tập lệnh tuyệt vời. Đối với những người có các file trích dẫn CSV kép (đọc hầu hết mọi người) thêm 'bọc trong '\ "'` để fields terminated by ','... nó thậm chí làm việc với CSV một phần đôi trích dẫn.
Joel Mellon

3
Tôi nghĩ ý bạn là ENCLOSED BY '\"'... ngoài ra, rất nhiều người sẽ cần LINES TERMINATED BY '\r\n'nếu sử dụng CSV từ Windows. Và cuối cùng, thoát khỏi tên trường với backticks là khôn ngoan trong trường hợp có nhiều không gian:$columns .= "`$column` varchar(250)";
DLO

1
Câu trả lời này tốt hơn nhiều so với câu trả lời được chấp nhận. Đặc biệt, nó cho phép những gì OP yêu cầu, và tôi cũng muốn: "hàng dữ liệu đầu tiên được sử dụng làm tên cột". (Tôi thích một tập lệnh bằng Python, vì vậy tôi không phải cài đặt PHP, nhưng sẽ không khó để chuyển nó.)
LarsH

2
@YumYumYum Bạn có thể nói rõ hơn về vấn đề bạn đang gặp phải không?
Hawkee

Tôi có thể mua cho bạn một cốc bia?
Joe

4

nếu bạn có khả năng cài đặt phpadmin, có một phần nhập nơi bạn có thể nhập tệp csv vào cơ sở dữ liệu của mình, thậm chí có một hộp kiểm để đặt tiêu đề thành dòng đầu tiên của tệp chứa tên cột bảng (nếu điều này được bỏ chọn, dòng đầu tiên sẽ trở thành một phần của dữ liệu


Tôi thực sự ngạc nhiên khi bạn phải sử dụng một tiện ích bổ sung như phpadmin để có được chức năng này, Cảm ơn câu trả lời của bạn
chrisfs

Tôi vừa làm một ngày của tôi
Đánh dấu

4

Trước tiên, hãy tạo một bảng trong cơ sở dữ liệu với số cột giống nhau trong tệp csv.

Sau đó sử dụng truy vấn sau

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

Còn nếu tôi muốn bỏ qua một cột trong csv thì sao?
Marci-man

3

Để tải dữ liệu từ tệp văn bản hoặc tệp csv, lệnh là

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

Trong lệnh trên, trong trường hợp của tôi chỉ có một cột được tải nên không có "kết thúc bởi" và "được bao bởi" vì vậy tôi giữ nó trống, người khác lập trình có thể nhập ký tự phân tách. ví dụ. , (dấu phẩy) hoặc "hoặc; hoặc bất kỳ thứ gì.

** dành cho những người đang sử dụng mysql phiên bản 5 trở lên **

Trước khi tải tệp vào mysql phải đảm bảo rằng dòng kéo bên dưới được thêm vào bên etc/mysql/my.cnf

để chỉnh sửa lệnh my.cnf là

sudo vi /etc/mysql/my.cnf

[mysqld]  
local-infile

[mysql]  
local-infile  

3

Nếu bạn bắt đầu mysql là "mysql -u -p --local-infile", nó sẽ hoạt động tốt


2

Tôi đã viết một số mã để thực hiện việc này, tôi sẽ đưa vào một vài đoạn mã:

$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

Sau đó, lấy tiêu đề CSV để bạn có thể cho mysql biết cách nhập (lưu ý: đảm bảo rằng các cột mysql của bạn khớp chính xác với các cột csv):

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

Sau đó, gửi truy vấn của bạn đến máy chủ 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

Tôi đã vật lộn với điều này trong một thời gian. Vấn đề không nằm ở cách tải dữ liệu, mà là cách xây dựng bảng để chứa nó. Bạn phải tạo một câu lệnh DDL để xây dựng bảng trước khi nhập dữ liệu.

Đặc biệt khó khăn nếu bảng có một số lượng lớn các cột.

Đây là một tập lệnh python (gần như) thực hiện công việc:

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

Vấn đề mà nó để lại để giải quyết là khai báo kiểu dữ liệu và tên trường cuối cùng được kết thúc bằng dấu phẩy và trình phân tích cú pháp mySQL sẽ không chấp nhận điều đó.

Tất nhiên nó cũng có vấn đề là nó sử dụng kiểu dữ liệu TEXT cho mọi trường. Nếu bảng có vài trăm cột, thì VARCHAR (64) sẽ làm cho bảng quá lớn.

Điều này dường như cũng bị phá vỡ ở số cột tối đa cho mySQL. Đó là thời điểm chuyển sang Hive hoặc HBase nếu bạn có thể.


1

Đây là cách tôi đã làm điều đó trong Python bằng cách sử dụng 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()

Những điểm chính

  • Sử dụng các câu lệnh chuẩn bị sẵn cho INSERT
  • Mở tệp.csv ở dạng 'rb'nhị phân
  • Một số tệp CSV có thể cần điều chỉnh , chẳng hạn như skipinitialspacetùy chọn.
  • Nếu 255không đủ rộng, bạn sẽ gặp lỗi trên INSERT và phải bắt đầu lại.
  • Điều chỉnh các loại cột, ví dụ: ALTER TABLE t MODIFY `Amount` DECIMAL(11,2);
  • Thêm khóa chính , ví dụ:ALTER TABLE t ADD `id` INT PRIMARY KEY AUTO_INCREMENT;

0

Nhập tệp CSV vào bảng 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

lượt truy cập: http://www.webslessons.com/2014/02/import-csv-files-using-php-and-mysql.html


0

Như những người khác đã đề cập, tệp tin cục bộ tải dữ liệu hoạt động tốt. Tôi đã thử tập lệnh php mà Hawkee đã đăng, nhưng không hiệu quả với tôi. Thay vì gỡ lỗi nó, đây là những gì tôi đã làm:

1) sao chép / dán hàng tiêu đề của tệp CSV vào tệp txt và chỉnh sửa bằng emacs. thêm dấu phẩy và CR giữa mỗi trường để mỗi trường nằm trên dòng riêng.
2) Lưu tập tin đó như FieldList.txt
3) chỉnh sửa các tập tin bao gồm defns cho từng lĩnh vực (nhất là varchar, nhưng khá một vài là int (x). Thêm create table tablename (đến đầu của tập tin và) đến cuối tệp. Lưu nó dưới dạng CreateTable.sql
4) khởi động máy khách mysql với đầu vào từ tệp Createtable.sql để tạo bảng
5) khởi động máy khách mysql, sao chép / dán vào hầu hết lệnh 'LOAD DATA INFILE' thay thế bảng của tôi tên và tên tệp csv. Dán vào tệp FieldList.txt. Hãy chắc chắn bao gồm 'BỎ QUA 1 DÒNG' trước khi dán vào danh sách trường

Nghe có vẻ nhiều việc, nhưng dễ dàng với emacs .....


0

Sử dụng ứng dụng TablePlus: Nhấp chuột phải vào tên bảng từ bảng bên phải Chọn Nhập ...> Từ CSV Chọn tệp CSV Xem lại đối sánh cột và nhấn Nhập Tất cả là xong!


-3

Tôi đã lên google tìm kiếm nhiều cách để nhập csv vào mysql, bao gồm "load data infile", sử dụng bàn làm việc mysql, v.v.

khi tôi sử dụng nút nhập bàn làm việc mysql, trước tiên, bạn cần phải tự tạo bảng trống, tự đặt từng loại cột. Lưu ý: bạn phải thêm cột ID ở cuối làm khóa chính chứ không phải null và auto_increment, nếu không, nút nhập sẽ không hiển thị sau này. Tuy nhiên, khi tôi bắt đầu tải tệp CSV, không có gì được tải, có vẻ như là một lỗi. Tôi từ bỏ.

Thật may mắn, cách dễ dàng nhất cho đến nay mà tôi tìm thấy là sử dụng mysql của Oracle cho excel. bạn có thể tải xuống từ đây mysql cho excel

Đây là những gì bạn sẽ làm: mở tệp csv trong excel, tại tab Dữ liệu, tìm nút mysql cho excel

chọn tất cả dữ liệu, nhấp vào xuất sang mysql. Lưu ý đặt cột ID làm khóa chính.

khi hoàn tất, hãy truy cập bàn làm việc mysql để thay đổi bảng, chẳng hạn như loại tiền tệ phải là số thập phân (19,4) đối với số thập phân lớn (10,2) để sử dụng thường xuyên. loại trường khác có thể được đặt thành varchar (255).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.