Python:通过空白 csv 迭代引发 StopIteration 错误

标签 python csv error-handling sqlite

我是一个新的 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/

相关文章:

Python在格式化表达式中对字典进行排序

python ctypes - 包装空指针

csv - 在 Elasticsearch 中导入 CSV 文件

r - 有没有办法将具有不同行长度的 csv 文件扫描到列表中?

javascript - 以 HTML 格式显示上传后的 CSV 内容

Python/Django - 异常值 : 'WSGIRequest' object has no attribute 'Meta'

Python 从 SIGINT 上的套接字接收中断

java - Java 新手 : Constructor error control

node.js - 将数据流式传输到 BigQuery 时没有错误响应

python - 无法从 python3/paramiko 捕获多个异常