如何在不事先知道列数的情况下将CSV文件导入Python中的sqlite3?

时间:2016-05-31 23:01:33

标签: python csv sqlite

我目前正在尝试使用Python将CSV文件导入到SQLite数据库中,使用顶部字段作为列名,但我需要能够导入任何CSV文件,无论它有多少列。我知道如何使用csv顶行来创建列名,但是我看到的关于在cthon中将csv文件导入数据库的每个例子,python程序都指定了列数。但是,该程序将让用户在输入框中提供csv文件名,允许他们选择不同的文件名,因此我不会提前知道需要分配多少列。我将如何制作它以便程序自动检测列数并相应地定义表格?到目前为止,我有类似的东西(不完全是一个很好的例子),但它默认只有两列。哦,我稍后会更改它,为用户添加一个输入要打开的文件名的选项,所以不要担心(主要是在不同的模块中实现)。

import csv, sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("CREATE TABLE t (col1, col2);")

with open('data.csv','rb') as fin: 

    dr = csv.DictReader(fin) #dr assigned value in DictReader
    to_db = [(i['col1'], i['col2']) for i in dr] #

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

更新:
我现在的代码是:

import csv, sqlite3
from Tkinter import *
from tkFileDialog  import askopenfilename






def choosefilename():
    return askopenfilename()



def main():
    con = sqlite3.connect(":memory:")

    csvFileName = choosefilename()
    cur = con.cursor()
    with open(csvFileName,'rb') as fin:
        data_csv = csv.DictReader(fin)
        column_count = len(list(list(data_csv))[0])
        create_table_statement = "CREATE TABLE t ("
        for column in xrange(1, column_count):
            create_table_statement = create_table_statement + 'col{0}'.format(column)
        create_table_statement = create_table_statement + ');'
        cur.execute(create_table_statement)
        [cur.execute('INSERT INTO t values ('+'%s,'*column_count[:-1]+')', d) for d in data_csv]



Button(text='File Open', command = choosefilename).pack(fill="x")
main()

它本身不会出错,但是当您尝试退出打开的文件按钮框时它会冻结。

3 个答案:

答案 0 :(得分:4)

如果您愿意使用pandas库,可以使用两个函数轻松实现:

Dataframe.to_sql

将返回一个dataframe对象,然后使用Dataframe方法

{{1}}

创建数据库。关于处理你的csv的标题,熊猫应该非常聪明。您可能只需要使用默认参数。

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html

答案 1 :(得分:2)

import csv, sqlite3

con = sqlite3.connect(":memory:")
with closing(con.cursor()) as cur:
    with open('data.csv','rb') as fin:
        data_csv = csv.read(fin)
        column_count = len(list(list(data_csv)[0])
        create_table_statement = "CREATE TABLE t ("
        for column in xrange(1, column_count):
            create_table_statement = create_table_statement + 'col{0},'.format(column)
        create_table_statement = create_table_statement[:-1] + ');'
        cur.execute(create_table_statement)
        [cur.execute('INSERT INTO t values ('+'%s,'*column_count[:-1]+')', d) for d in data_csv]

希望有所帮助。

答案 2 :(得分:-1)

在WITH ??之前一定不要尝试。

con = sqlite3.connect(":memory:")
try:
    with closing(sqlite3.connect(":memory:")) as con:

也迷糊了一个

column_count = len(list(list(data_csv)[0]))