我正在尝试将csv文件导入到我正在使用python编写的sqlite3数据库中。我很擅长以这种方式导入数据,而且一般都是以sqlite3导入。
我得到的数据文件在开头往往有不规则的格式,但我想要的行总是以日期字段(dd / mm / yy)和时间字段(hh:mm:ss)开头。 示例文件如下:
Hello I am a file, , , ,
I am a type of csv file, , , ,
Date, Time, ID number, Message
12/12/2012, 13:12:13, 1, Hello World
13/12/2012, 13:12:13, 2, Goodbye
所以我想导入第4行和第5行(以及带有日期的所有后续行),但跳过描述文件和列标题的前3行。
到目前为止,我已经获得了读取数据的代码,然后将其与唯一标识符(logID)一起放入表中,但此刻我只是从第4行开始阅读 - 我想要对于文件没有3个前导行模糊的情况的更通用的解决方案。
#code above here opens the database and creates a cursor
with open(file) as csvfile:
reader = csv.reader(csvfile, dialect='excel')
for row in reader:
if reader.line_num >= 4:
values = logID + str(row[0]) + str(row[1]) + str(row[2]) + str(row[3])
cursor.execute("INSERT INTO table VALUES(" +values+ ");")
提前感谢您的帮助!
答案 0 :(得分:2)
尝试将row
中的第一项转换为Python datetime.datetime对象。如果有效,请处理该行,如果不是,则通过循环处理continue:
import datetime as DT
with open(file, 'rb') as csvfile:
reader = csv.reader(csvfile, dialect='excel')
for row in reader:
try:
date = DT.datetime.strptime(row[0], '%m/%d/%Y')
except ValueError:
continue
args = [logID] + row
sql = "INSERT INTO table VALUES ({})".format(', '.join(['?']*len(args)))
cursor.execute(sql, args)
以上内容适用于中小型CSV。如果您有一个巨大的CSV文件,每行调用一次cursor.execute
可能会很慢。要提高性能,请一次读取一行(例如1000行),并将要插入的值累积到列表列表manyargs
中。然后拨打
cursor.executemany("INSERT INTO table VALUES(?,?,?,?,?)", manyargs)
每个块一次。
顺便说一下,使用字符串格式构建SQL命令,例如:
cursor.execute("INSERT INTO table VALUES(" +values+ ");")
可能存在安全风险。恶意构造的CSV文件可以利用此行来运行任意SQL命令(请参阅SQL injection和Little Bobby Tables)。为了防止这种情况,请使用参数化SQL:
cursor.execute("INSERT INTO table VALUES(?,?,?,?,?)", args)
?
是一个地标 - 每个字段值都有一个地标。 args
是包含您要插入的值的序列(例如元组或列表)。请注意,args
作为第二个参数传递给cursor.execute
。您不必将args
中的值转换为字符串(尽管在这种情况下,它们是字符串,因为csv.reader
生成字符串列表)。 sqlite3模块将为您处理参数的引用。