2013-08-13 14 views
13

czytam to: Importing a CSV file into a sqlite3 database table using PythonLuzem wstawić ogromne danych do SQLite przy użyciu Python

i wydaje się, że każdy sugeruje użycie wiersz po wierszu czytanie zamiast korzystania z SQLite .import luzem. To jednak spowoduje, że wstawianie będzie naprawdę powolne, jeśli masz miliony rzędów danych. Czy jest jakiś inny sposób na obejście tego?

Aktualizacja: Próbowałem następującego kodu, aby wstawić wiersz po wierszu, ale prędkość nie jest tak dobra, jak się spodziewałem. Czy mimo to poprawić to

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

Odpowiedz

17

Podziel swoje dane na porcje w locie za pomocą wyrażeń generatora, dokonaj wstawek wewnątrz transakcji. Oto cytat z sqlite optimization FAQ:

Chyba już w transakcji, każda instrukcja SQL ma nową transakcja zaczęło do niego. Jest to bardzo kosztowne, ponieważ wymaga ponownego otworzenia, zapisania i zamknięcia pliku kroniki dla dla każdego oświadczenia . Można tego uniknąć, pakując sekwencje instrukcji SQL z BEGIN TRANSACTION; i TRANS TRANSAKCJA; sprawozdania. To przyspieszenie jest również uzyskiwane dla instrukcji, które nie zmieniają bazy danych.

Here's jak może wyglądać twój kod.

Również, sqlite ma zdolność do import CSV files.

+0

Może SQLite importować wiele plików CSV na raz. Nie mogłem znaleźć sposobu na zrobienie tego? – Shar

+0

Nie sądzę, że możliwe jest zaimportowanie wielu plików CSV jednocześnie. Dzielenie danych na części i wstawianie ich do transakcji powinno być moim zdaniem najlepszym rozwiązaniem. – alecxe

+0

Dziękujemy! Myślę, że pójdę z tym. – Shar

14

Sqlite może zrobić tens of thousands of inserts per second, po prostu upewnij się, aby zrobić je wszystkie w jednej transakcji przez otaczający wkładki z BEGIN i COMMIT. (executemany() robi to automatycznie.)

Jak zwykle, nie optymalizuj, zanim się zorientujesz, że prędkość będzie problemem. Najpierw przetestuj najprostsze rozwiązanie i zoptymalizuj tylko, jeśli prędkość jest niedopuszczalna.

+0

Dzięki! Próbuję tego teraz i opowiem o prędkości. – Shar

+0

Właśnie próbowałem tego, co sugerujesz, wstawiając wiersz po linii. Prędkość nie jest taka zła, ale nadal nie jest tak szybka, jak mam nadzieję. Może mój kod nie był wystarczająco napisany. Zaktualizowałem go w powyższym pytaniu. Masz jakieś sugestie? – Shar

23

Ponieważ jest to najlepszy wynik w wyszukiwarce Google, pomyślałem, że aktualizacja tego pytania może być przyjemna.

Z python sqlite docs można użyć

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) 

Użyłem tej metody, aby popełnić ponad 50k wkładki wierszy naraz i to błyskawicznie.

+1

Błyskawicznie działa także dlatego, że używasz sqlite jako bazy danych w pamięci ... – aramaki

+0

Zmniejszono 2-minutowe zadanie tworzenia do mniej niż sekundy! i jest to baza danych plików, więc i tak jest błyskawica – Math

Powiązane problemy