2010-05-22 506 views
69

我有一個CSV文件,我想用Python將這個文件批量導入到我的sqlite3數據庫中。該命令是「.import .....」。但它似乎不能像這樣工作。任何人都可以給我一個如何在sqlite3中做的例子嗎?我正在使用Windows以防萬一。 謝謝使用Python將CSV文件導入到sqlite3數據庫表中

+3

請提供** actual **命令和** ** actual **錯誤消息。 「導入....」可以是任何東西。 「不能工作」對我們來說太模糊了。沒有細節,我們無法幫助。 – 2010-05-22 11:30:23

+1

正如我所說的實際命令是「.import」,它說新的語法錯誤「.import」 – Hossein 2010-05-22 11:36:43

+8

請實際發佈實際命令的問題。實際上請在問題中發佈實際的錯誤消息。請不要添加簡單重複的評論。請用實際複製並粘貼您實際正在做的事情來更新問題。 – 2010-05-22 11:46:27

回答

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

如果您遇到同樣的問題,請執行以下操作:確保將col1和col2更改爲csv文件中的列標題。並通過在最後調用con.close()關閉與數據庫的連接。 – Jonas 2016-08-08 21:31:43

+0

謝謝,@Jonas。更新後。 – bernie 2016-08-08 21:38:10

+0

當我嘗試這種方法時,我總是收到'不是所有在字符串格式化過程中轉換的參數。 – Whitecat 2016-09-01 23:27:53

10

.import命令是sqlite3命令行工具的一個功能。要在Python中完成,只需使用Python提供的任何工具(例如csv module)加載數據,然後按照慣例插入數據。

這樣,您也可以控制插入哪些類型,而不是依賴sqlite3看似沒有記錄的行爲。

+0

沒有必要準備插頁。 SQL語句和編譯結果的來源保存在緩存中。 – 2010-06-17 04:13:37

+0

@John Machin:有沒有鏈接到SQLite如何做到這一點? – 2010-06-17 07:34:35

+0

@Marcelo:如果您對如何完成它(爲什麼?)感興趣,請查看sqlite源代碼或在sqlite郵件列表中詢問。 – 2010-06-17 07:54:23

8

非常感謝伯尼的answer!不得不調整了一點 - 這裏是爲我工作:

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() 

我的文本文件(PC.txt)看起來是這樣的:

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

unicode()函數在哪裏? – 2016-12-02 20:39:05

49

創建對文件的sqlite的連接磁盤作爲練習留給讀者......但現在有一個由熊貓庫

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

謝謝。我遇到了熊貓問題。我的csv由';'分隔並在條目中有','。熊貓在read_csv上給出錯誤。用逗號w/out讀取條目的任何設置都會暫時替換? – 2016-06-19 06:42:20

+3

使用sep =';'。熊貓文件清楚地概述瞭如何處理這個問題。 – 2016-06-20 08:01:52

+2

有沒有辦法使用熊貓,但不使用RAM ?,我有一個巨大的.csv(7GB)我不能導入爲數據幀,然後附加到數據庫。 – 2016-11-18 12:57:48

9

我的2美分(更多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

如果len(feildslLeft)> 0:總是爲true,所以引發異常。請檢查並更正此問題。 – shubham 2016-01-09 22:34:24

+0

任何方式做到這一點,而不必fseek(),以便它可以用於流? – mwag 2016-11-20 21:29:37

4

可以使用blaze & odo有效

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

奧多將CSV文件存儲到data.db(SQLite數據庫)架構data

或者你用odo下做到這一點直接,沒有blaze。無論哪種方式都很好。請閱讀documentation

相關問題