Массовая вставка огромных данных в SQLite с использованием Python

Я прочитал это: Импорт CSV файла в таблицу базы данных sqlite3 с использованием Python

и кажется, что каждый предлагает использовать линейное чтение вместо использования массового.import из SQLite. Однако это сделает вставку очень медленной, если у вас есть миллионы строк данных. Есть ли другой способ обойти это?

Обновление: я попробовал следующий код, чтобы вставлять строки за строкой, но скорость не так хороша, как я ожидал. Есть ли способ улучшить его

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()

Ответ 1

Разделите свои данные на куски "на лету" с помощью выражений генератора, сделайте вставки внутри транзакции. Здесь цитата из оптимизации оптимизации sqlite:

Если в транзакции уже не было транзакции, каждая инструкция SQL имеет для нее новую транзакцию. Это очень дорого, поскольку для каждого заявления требуется повторное открытие, запись и закрытие файла журнала. Этого можно избежать, обертывая последовательности операторов SQL с помощью BEGIN TRANSACTION; и КОНЕЦ ОПЕРАЦИИ; заявления. Это ускорение также получается для операторов, которые не изменяют базу данных.

Вот как выглядит ваш код.

Кроме того, sqlite имеет возможность импортировать CSV файлы.

Ответ 2

Поскольку это лучший результат в поиске Google, я подумал, что было бы неплохо обновить этот вопрос.

Из документов python sqlite вы можете использовать

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)

Я использовал этот метод для фиксации более 50 тыс. Строк вставки за раз, и это было молниеносно.

Ответ 3

Sqlite может делать десятки тысяч вставок в секунду, просто убедитесь, что все они выполняются в одной транзакции, окружая вставки с помощью BEGIN и COMMIT. (executemany() делает это автоматически.)

Как всегда, не оптимизируйте, прежде чем вы узнаете, что скорость будет проблемой. Сначала проверьте самое легкое решение и только оптимизируйте, если скорость неприемлема.