Bạn đúng đó .import
là cách để đi, nhưng đó là một lệnh từ trình bao SQLite3.exe. Rất nhiều câu trả lời hàng đầu cho câu hỏi này liên quan đến các vòng lặp gốc python, nhưng nếu tệp của bạn lớn (của tôi là 10 ^ 6 đến 10 ^ 7 bản ghi), bạn muốn tránh đọc mọi thứ thành gấu trúc hoặc sử dụng vòng lặp / hiểu danh sách python gốc (mặc dù tôi đã không cho họ thời gian để so sánh).
Đối với các tệp lớn, tôi tin rằng tùy chọn tốt nhất là tạo bảng trống trước bằng cách sử dụng sqlite3.execute("CREATE TABLE...")
, tách các tiêu đề khỏi tệp CSV của bạn và sau đó sử dụng subprocess.run()
để thực thi câu lệnh nhập của sqlite. Vì phần cuối cùng là phần tôi tin rằng phù hợp nhất nên tôi sẽ bắt đầu với phần đó.
subprocess.run()
from pathlib import Path
db_name = Path('my.db').resolve()
csv_file = Path('file.csv').resolve()
result = subprocess.run(['sqlite3',
str(db_name),
'-cmd',
'.mode csv',
'.import '+str(csv_file).replace('\\','\\\\')
+' <table_name>'],
capture_output=True)
Giải thích
Từ dòng lệnh, lệnh bạn đang tìm là sqlite3 my.db -cmd ".mode csv" ".import file.csv table"
. subprocess.run()
chạy một quy trình dòng lệnh. Đối số tới subprocess.run()
là một chuỗi các chuỗi được hiểu là một lệnh, theo sau là tất cả các đối số của nó.
sqlite3 my.db
mở cơ sở dữ liệu
-cmd
cờ sau khi cơ sở dữ liệu cho phép bạn chuyển nhiều lệnh theo dõi vào chương trình sqlite. Trong shell, mỗi lệnh phải nằm trong dấu ngoặc kép, nhưng ở đây, chúng chỉ cần là phần tử riêng của chuỗi
'.mode csv'
làm những gì bạn mong đợi
'.import '+str(csv_file).replace('\\','\\\\')+' <table_name>'
là lệnh nhập.
Thật không may, vì quy trình con chuyển tất cả các phần theo dõi thành các -cmd
chuỗi được trích dẫn, bạn cần tăng gấp đôi dấu gạch chéo ngược của mình nếu bạn có đường dẫn thư mục windows.
Tước tiêu đề
Không thực sự là điểm chính của câu hỏi, nhưng đây là những gì tôi đã sử dụng. Một lần nữa, tôi không muốn đọc toàn bộ tệp vào bộ nhớ tại bất kỳ thời điểm nào:
with open(csv, "r") as source:
source.readline()
with open(str(csv)+"_nohead", "w") as target:
shutil.copyfileobj(source, target)