2010-05-22 44 views
69

Tôi có tệp CSV và tôi muốn nhập số lượng lớn tệp này vào cơ sở dữ liệu sqlite3 của mình bằng Python. lệnh là ".import .....". nhưng có vẻ như nó không thể hoạt động như thế này. Bất cứ ai có thể cho tôi một ví dụ về làm thế nào để làm điều đó trong sqlite3? Tôi đang sử dụng cửa sổ chỉ trong trường hợp. Cảm ơnNhập tệp CSV vào bảng cơ sở dữ liệu sqlite3 bằng cách sử dụng Python

+3

Vui lòng cung cấp lệnh ** ** thực tế không hoạt động và thông báo lỗi ** thực tế **. "nhập ...." có thể là bất cứ điều gì. "không thể làm việc" là quá mơ hồ đối với chúng tôi để đoán. Không có chi tiết, chúng tôi không thể giúp. –

+1

lệnh thực tế như tôi đã nói là ".import" và nó nói lỗi cú pháp mới ".import" – Hossein

+8

Hãy thực sự đăng lệnh thực tế trong câu hỏi. Vui lòng thực sự đăng thông báo lỗi thực tế trong câu hỏi. Vui lòng không thêm nhận xét mà chỉ cần lặp lại mọi thứ. Vui lòng cập nhật câu hỏi bằng cách sao chép và dán thực tế những gì bạn đang thực sự làm. –

Trả lời

95
import csv, sqlite3 

con = sqlite3.connect(":memory:") 
cur = con.cursor() 
cur.execute("CREATE TABLE t (col1, col2);") # use your column names here 

with open('data.csv','rb') as fin: # `with` statement available in 2.5+ 
    # csv.DictReader uses first line in file for column headings by default 
    dr = csv.DictReader(fin) # comma is default delimiter 
    to_db = [(i['col1'], i['col2']) for i in dr] 

cur.executemany("INSERT INTO t (col1, col2) VALUES (?, ?);", to_db) 
con.commit() 
con.close() 
+2

Trong trường hợp bạn có cùng một vấn đề tôi đã làm: Đảm bảo thay đổi col1 và col2 thành tiêu đề cột trong tệp csv. Và đóng kết nối tới cơ sở dữ liệu bằng cách gọi con.close() ở cuối. – Jonas

+0

Xin cảm ơn, @Jonas. Đã cập nhật bài đăng. – bernie

+0

Tôi tiếp tục nhận 'không phải tất cả đối số được chuyển đổi trong khi định dạng chuỗi' khi tôi thử phương pháp này. – Whitecat

10

Lệnh .import là tính năng của công cụ dòng lệnh sqlite3. Để làm điều đó trong Python, bạn chỉ cần tải dữ liệu bằng cách sử dụng bất kỳ cơ sở Python nào, chẳng hạn như csv module và chèn dữ liệu như bình thường.

Bằng cách này, bạn cũng có quyền kiểm soát những loại được chèn, thay vì dựa vào hành vi dường như không có giấy tờ của sqlite3.

+0

Không cần chuẩn bị phần chèn. Nguồn của các câu lệnh SQL và các kết quả được biên dịch được lưu trong bộ nhớ cache. –

+0

@ John Machin: Có liên kết đến cách SQLite thực hiện việc này không? –

+0

@Marcelo: Nếu bạn quan tâm đến CÁCH nó được thực hiện (tại sao?), Hãy tìm trong nguồn sqlite hoặc hỏi về danh sách gửi thư sqlite. –

8

Rất cám ơn cho bernie của answer! Phải tinh chỉnh nó một chút - đây là những gì làm việc cho tôi:

import csv, sqlite3 
conn = sqlite3.connect("pcfc.sl3") 
curs = conn.cursor() 
curs.execute("CREATE TABLE PCFC (id INTEGER PRIMARY KEY, type INTEGER, term TEXT, definition TEXT);") 
reader = csv.reader(open('PC.txt', 'r'), delimiter='|') 
for row in reader: 
    to_db = [unicode(row[0], "utf8"), unicode(row[1], "utf8"), unicode(row[2], "utf8")] 
    curs.execute("INSERT INTO PCFC (type, term, definition) VALUES (?, ?, ?);", to_db) 
conn.commit() 

tập tin văn bản của tôi (kB) trông như thế này:

1 | Term 1 | Definition 1 
2 | Term 2 | Definition 2 
3 | Term 3 | Definition 3 
6
#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import sys, csv, sqlite3 

def main(): 
    con = sqlite3.connect(sys.argv[1]) # database file input 
    cur = con.cursor() 
    cur.executescript(""" 
     DROP TABLE IF EXISTS t; 
     CREATE TABLE t (COL1 TEXT, COL2 TEXT); 
     """) # checks to see if table exists and makes a fresh table. 

    with open(sys.argv[2], "rb") as f: # CSV file input 
     reader = csv.reader(f, delimiter=',') # no header information with delimiter 
     for row in reader: 
      to_db = [unicode(row[0], "utf8"), unicode(row[1], "utf8")] # Appends data from CSV file representing and handling of text 
      cur.execute("INSERT INTO neto (COL1, COL2) VALUES(?, ?);", to_db) 
      con.commit() 
    con.close() # closes connection to database 

if __name__=='__main__': 
    main() 
+0

Hàm unicode() ở đâu? –

49

Tạo một kết nối sql vào một tập tin trên đĩa được để lại dưới dạng tập thể dục cho người đọc ... nhưng hiện tại có hai lớp lót được thực hiện bởi thư viện gấu trúc

df = pandas.read_csv(csvfile) 
df.to_sql(table_name, conn, if_exists='append', index=False) 
+0

cảm ơn bạn. Tôi gặp vấn đề với gấu trúc. csv của tôi được phân cách bởi ';' và có ',' trong mục. panda cho lỗi trên read_csv. bất kỳ cài đặt nào để đọc các mục nhập bằng dấu phẩy sẽ bị thay thế tạm thời? –

+3

sử dụng sep = ';'. Tài liệu về gấu trúc nêu rõ cách xử lý vấn đề này. –

+2

có cách nào để sử dụng gấu trúc nhưng không sử dụng RAM ?, tôi có một tệp .csv (7gb) lớn không thể nhập dưới dạng một khung dữ liệu và sau đó nối thêm vào DB. –

9

2 xu của tôi (thêm ge neric):

import csv, sqlite3 
import logging 

def _get_col_datatypes(fin): 
    dr = csv.DictReader(fin) # comma is default delimiter 
    fieldTypes = {} 
    for entry in dr: 
     feildslLeft = [f for f in dr.fieldnames if f not in fieldTypes.keys()] 
     if not feildslLeft: break # We're done 
     for field in feildslLeft: 
      data = entry[field] 

      # Need data to decide 
      if len(data) == 0: 
       continue 

      if data.isdigit(): 
       fieldTypes[field] = "INTEGER" 
      else: 
       fieldTypes[field] = "TEXT" 
     # TODO: Currently there's no support for DATE in sqllite 

    if len(feildslLeft) > 0: 
     raise Exception("Failed to find all the columns data types - Maybe some are empty?") 

    return fieldTypes 


def escapingGenerator(f): 
    for line in f: 
     yield line.encode("ascii", "xmlcharrefreplace").decode("ascii") 


def csvToDb(csvFile, outputToFile = False): 
    # TODO: implement output to file 

    with open(csvFile,mode='r', encoding="ISO-8859-1") as fin: 
     dt = _get_col_datatypes(fin) 

     fin.seek(0) 

     reader = csv.DictReader(fin) 

     # Keep the order of the columns name just as in the CSV 
     fields = reader.fieldnames 
     cols = [] 

     # Set field and type 
     for f in fields: 
      cols.append("%s %s" % (f, dt[f])) 

     # Generate create table statement: 
     stmt = "CREATE TABLE ads (%s)" % ",".join(cols) 

     con = sqlite3.connect(":memory:") 
     cur = con.cursor() 
     cur.execute(stmt) 

     fin.seek(0) 


     reader = csv.reader(escapingGenerator(fin)) 

     # Generate insert statement: 
     stmt = "INSERT INTO ads VALUES(%s);" % ','.join('?' * len(cols)) 

     cur.executemany(stmt, reader) 
     con.commit() 

    return con 
+0

nếu len (feildslLeft)> 0: luôn đúng, vì vậy hãy đưa ra một ngoại lệ. Vui lòng xem lại và sửa lỗi này. – shubham

+0

Bất kỳ cách nào để thực hiện điều này mà không cần phải fseek(), để nó có thể được sử dụng trên các luồng? – mwag

4

Bạn có thể làm điều này bằng blaze & odo hiệu quả

import blaze 
csv_path = 'data.csv' 
bz.odo(csv_path, 'sqlite:///data.db::data') 

Odo sẽ lưu trữ các tập tin csv để data.db (cơ sở dữ liệu SQLite) thuộc schema data

Hoặc bạn sử dụng odo trực tiếp, không có blaze. Dù bằng cách nào cũng tốt. Đọc này documentation

Các vấn đề liên quan