我是一个新的python用户并且遇到了问题。如果解决方案很明显,我会提前道歉。
我打算能够获取潜在的大量csv文件并将它们插入数据库,然后我可以使用sql查询报告和其他甜食,我有以下代码:
import csv
# Establishes a db connection and returns connection and cursor obj
# creates dbName.db file in given location
def openDB (dbName,location):
import sqlite3,os
os.chdir(location)
conn = sqlite3.connect(dbName)
c = conn.cursor()
return conn,c
# Uses connection, cursor, csv obj and writes into table
def insertFromCsv (csvObj,connection,cursor,tableName):
c = cursor
# Just added this condition to check for blank files
# but I'm not sure if this is appropriate..
rowCount = sum(1 for row in csvObj)
if rowCount > 0:
csvObj.next()
i = 0
for row in csvObj:
tablerow = ", ".join('"' + value + '"' for value in row)
insertSQL = "INSERT INTO '%s' VALUES (%s)" % (tableName,tablerow)
c.execute(insertSQL)
i += 1
connection.commit()
print '%s rows committed to table %s' % (i, tableName)
# creates the .reader obj
reader = csv.reader(csvFile)
# extract column names from csv header
tableFields = reader.next()
# formats the column names for the INSERT statement coming up
tableFields = ", ".join('"' + field + '"' for field in tableFields)
DB = openDB('foo.db','../bar')
tableName = myTable
insertFromCsv(reader,DB[0],DB[1],myTable)
insertFromCsv()将csv文件.reader对象,sqlite3数据库连接和游标对象以及要创建和插入的输出表作为输入。
直到最近,当我尝试输入一个仅包含标题的csv文件时,它一直工作正常。调用.next()方法后出现StopIteration错误。如何避免/我误解/忽视什么?
我感谢所有的帮助,欢迎任何批评!
答案 0 :(得分:1)
您之前已经耗尽了csvObj
迭代器:
rowCount = sum(1 for row in csvObj)
迭代器用完后,你就不能再调用它next()
而不会提升StopIteration
;你已经到了迭代器的末尾。
如果要测试空白CSV文件,请使用next()
function读取一行行,该行可以是默认值。例如,next(csvObj, None)
将返回None
,而不是在迭代器耗尽时传播StopIteration
异常。
接下来,使用 SQL参数创建一个通用SQL语句,然后使用cursor.executemany()
让数据库拉入所有行并为您插入:
header = next(csvObj, None)
if header:
tablerow = ", ".join(['?'] * len(row))
insertSQL = 'INSERT INTO "%s" VALUES (%s)' % (tableName, tablerow)
c.executemany(insertSQL, csvObj)
?
是一个SQL参数占位符; executemany()
会从csvObj
的每一行填写这些内容。
cursor.executemany()
如果csvObj
实际上是任何行,那么它对于INSERT
来说无关紧要;如果只存在标题而不存在,那么就不会执行实际的"..."
语句。
请注意,我使用li {
font-size: 100%;
}
li:nth-child(1) {
font-size: 90%;
}
li:nth-child(2) {
font-size: 80%;
}
li:nth-child(3) {
font-size: 70%;
}
li:nth-child(4) {
font-size: 60%;
}
双引号来正确引用表名,请参阅SQLite keywords;单引号用于字符串文字值,而不是表名。