我是一个新的 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 错误。如何避免这种情况/我误解/忽略了什么?
我感谢所有的帮助,欢迎任何批评!
最佳答案
您已经用完了之前行中的 csvObj
迭代器:
rowCount = sum(1 for row in csvObj)
一旦迭代器耗尽,如果不引发 StopIteration
,就不能再对其调用 next()
;您已经到达迭代器的末尾。
如果您想测试一个空白的 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
实际产生任何行都无关紧要;如果仅存在 header ,仅此而已,则不会执行任何实际的 INSERT
语句。
请注意,我使用了 "..."
双引号来正确引用表名,请参阅 SQLite keywords ;单引号用于字符串文字值,而不是表名。
关于Python:通过空白 csv 迭代引发 StopIteration 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39353985/