26

我读到这个:Importing a CSV file into a sqlite3 database table using Python

似乎每个人都建议使用逐行阅读而不是使用 SQLite 中的批量 .import。但是,如果您有数百万行数据,这将使插入变得非常缓慢。有没有其他方法可以规避这种情况?

更新:我尝试了以下代码逐行插入,但速度没有我预期的那么好。有没有办法改进它

for logFileName in allLogFilesName:
    logFile = codecs.open(logFileName, 'rb', encoding='utf-8')
    for logLine in logFile:
        logLineAsList = logLine.split('\t')
        output.execute('''INSERT INTO log VALUES(?, ?, ?, ?)''', logLineAsList)
    logFile.close()
connection.commit()
connection.close()
4

3 回答 3

46

由于这是谷歌搜索的最高结果,我认为更新这个问题可能会很好。

python sqlite docs你可以使用

import sqlite3

persons = [
    ("Hugo", "Boss"),
    ("Calvin", "Klein")
]

con = sqlite3.connect(":memory:")

# Create the table
con.execute("create table person(firstname, lastname)")

# Fill the table
con.executemany("insert into person(firstname, lastname) values (?,?)", persons)

我已经使用这种方法一次提交超过 50k 行插入,而且速度快如闪电。

于 2015-08-27T02:11:55.900 回答
24

使用生成器表达式将您的数据动态划分为块,在事务中进行插入。这是来自sqlite 优化常见问题解答的引用:

除非已经在事务中,否则每个 SQL 语句都会为其启动一个新事务。这是非常昂贵的,因为它需要重新打开、写入和关闭每个语句的日志文件。这可以通过使用 BEGIN TRANSACTION 包装 SQL 语句序列来避免;和结束交易;陈述。对于不改变数据库的语句,也可以获得这种加速。

这是您的代码的外观。

此外,sqlite 还可以导入 CSV 文件

于 2013-08-13T21:53:08.220 回答
18

Sqlite每秒可以进行数万次插入,只需确保在单个事务中通过使用 BEGIN 和 COMMIT 包围插入来完成所有这些。(executemany() 会自动执行此操作。)

与往常一样,在您知道速度将成为问题之前不要进行优化。首先测试最简单的解决方案,只有在速度不可接受时才进行优化。

于 2013-08-13T21:51:39.510 回答