Массовая вставка огромных данных в 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() делает это автоматически.)
Как всегда, не оптимизируйте, прежде чем вы узнаете, что скорость будет проблемой. Сначала проверьте самое легкое решение и только оптимизируйте, если скорость неприемлема.