2010-05-22 507 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

相关问题