以块为单位读取数据使用事务在Sqlite中插入块

时间:2015-07-08 08:00:12

标签: python csv sqlite transactions

我的问题是关于使用事务SQLite transaction for CSV importing以块为单位在Sqlite中导入数据集的旧帖子:

import csv, sqlite3, time

def chunks(data, rows=10000):

    for i in range (0, len(data), rows):

        yield data[i:i+rows]

if __name__ == "__main__":
    t = time.time()

con = sqlite3.connect('test.db')

cur = con.cursor()

cur.execute("DROP TABLE IF EXISTS sensor;")

cur.execute("CREATE TABLE sensor(key INT, reading REAL);")

filename = 'dummy.csv'

reader = csv.reader(open(filename,"r"))

divdata = chunks(list(reader))


for chunk in divdata:

    cur.execute('BEGIN TRANSACTION')

    for col1, col2 in chunk:

        cur.execute('INSERT INTO sensor (key, reading) VALUES (?, ?)', col1, col2))

    con.commit()

当csv.reader读取内存中的整个文件然后通过调用函数块来切断文件时,我正在寻找一个以块(例如,10k行)读取文件的解决方案,然后每个块都是像上面一样插入Sqlite表,直到插入整个文件。如何修改上述内容?

1 个答案:

答案 0 :(得分:0)

divdata = chunks(list(reader))

list(reader)将遍历整个CSV文件并将结果存储在列表中。你不想这样做,因为CSV文件非常庞大。

另外,您不想运行cur.execute("BEGIN TRANSACTION;"); sqlite3模块为您完成此任务。

在您通过CSV阅读器进行迭代时,请保留一个计数器。检查柜台并偶尔使用它。

for counter, row in enumerate(reader):
    if counter % CHUNK_SIZE == 0:
        cur.commit()
    cur.execute("INSERT INTO ...")

cur.commit()

(注意:我不认为像这样的大宗交易是一个好主意。也许它会有所帮助,但你必须先对它进行分析。)