将插入合并为一个事务 Python SQLite3

9 投票
4 回答
9766 浏览
提问于 2025-04-16 12:09

我正在尝试在SQLite3中插入成千上万的行数据,但插入的时间实在太长了。我听说如果把多个插入操作放在一个事务中,速度会大大提高。不过,我似乎无法让SQLite3跳过检查文件是否已经写入硬盘。

这是一个示例:

if repeat != 'y':
    c.execute('INSERT INTO Hand (number, word) VALUES (null, ?)', [wordin[wordnum]])
    print wordin[wordnum]

data.commit()

这是我开始时的代码。

data = connect('databasenew')
data.isolation_level = None
c = data.cursor()  
c.execute('begin')

但是,这似乎没有什么效果。如果有办法提高插入速度,我会非常感激。

4 个回答

1

(如果还有人想找这个问题的答案)

如果你要连续插入成千上万条数据,建议使用executemany这个方法。

可以看看这个链接:在sqlite3中插入大量记录(超过40,000条)的优化方法是什么

我之前遇到过很多(上百万条)的execute操作,花了大约30分钟才能完成 - 切换到executemany后,现在只需要大约10分钟。

2

这个链接 https://stackoverflow.com/a/3689929/1147726 回答了这个问题。执行 `execute('begin')` 并没有什么作用。看起来,调用 `connection.commit()` 就足够了。

3

根据Sqlite的说明,BEGIN事务应该用COMMIT来结束。

你可以手动使用BEGIN命令来开始一个事务。这样的事务通常会一直持续到下一个COMMIT或者ROLLBACK命令。不过,如果数据库被关闭,或者发生了错误,并且指定了ROLLBACK冲突解决算法,那么这个事务也会被ROLLBACK。想了解更多关于ROLLBACK冲突解决算法的信息,可以查看关于ON CONFLICT条款的文档。

所以,你的代码应该像这样:

data = connect('databasenew')
data.isolation_level = None
c = data.cursor()  
c.execute('begin')

if repeat != 'y':
    c.execute('INSERT INTO Hand (number, word) VALUES (null,?)', [wordin[wordnum]])
    print wordin[wordnum]

    data.commit()

    c.execute('commit')

撰写回答