2013-08-13 5 views
13

Я прочитал это: Importing a CSV file into a sqlite3 database table using PythonBulk вставки больших объемов данных в SQLite с помощью 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() 

ответ

17

Разделите свои данные на куски на лету, используя выражения генератора, сделайте вставки внутри транзакции. Вот цитата из sqlite optimization FAQ:

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

Here's как может выглядеть ваш код.

Кроме того, sqlite имеет возможность import CSV files.

+0

Может ли SQLite импортировать сразу несколько CSV-файлов. Я не мог найти способ сделать это? – Shar

+0

Не думайте, что можно импортировать сразу несколько файлов csv. Думаю, разделить данные на куски и вставить их в транзакции. – alecxe

+0

Спасибо! Думаю, я собираюсь пойти с этим. – Shar

14

Sqlite может сделать tens of thousands of inserts per second, просто убедитесь, что делать их все в одной транзакции, окружив вставки с НАЧАТЬ и COMMIT. (executemany() делает это автоматически.)

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

+0

Спасибо! Я пытаюсь это прямо сейчас и сообщит о скорости. – Shar

+0

Я просто попробовал, что вы предложили, вставляя строки за строкой. Скорость не так уж плоха, но все равно не так быстро, как я надеюсь. Возможно, мой код был недостаточно хорошо написан. Я обновил его в вопросе выше. Есть ли у вас какие-либо предложения? – Shar

23

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

С 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 строк вставки в то время, и это молниеносно.

+1

Это молниеносно также потому, что вы используете sqlite как базу данных в памяти ... – aramaki

+0

уменьшил задачу создания за 2 минуты дольше, чем секунду! и это файловая база данных, поэтому в любом случае это молния – Math

Смежные вопросы