2011-05-09 7 views
18

큰 (~ 1.6GB) CSV 파일을 "변환"하고 CSV의 특정 필드를 SQLite 데이터베이스에 삽입합니다.Python CSV SQLite

import csv, sqlite3 

conn = sqlite3.connect("path/to/file.db") 
conn.text_factory = str #bugger 8-bit bytestrings 
cur = conn.cur() 
cur.execute('CREATE TABLE IF NOT EXISTS mytable (field2 VARCHAR, field4 VARCHAR)') 

reader = csv.reader(open(filecsv.txt, "rb")) 
for field1, field2, field3, field4, field5 in reader: 
    cur.execute('INSERT OR IGNORE INTO mytable (field2, field4) VALUES (?,?)', (field2, field4)) 

모든 내가 제외에 예상대로 ... IT가 프로세스에 엄청난 시간이 소요 작동 :처럼 기본적으로 내 코드 보인다. 나는 그것을 잘못 코딩하고 있는가? 더 높은 성능을 얻고 내가 원하는 것을 성취 할 수있는 더 좋은 방법이 있습니까 (단순히 CSV의 몇 가지 필드를 SQLite 테이블로 변환하십시오)?

** EDIT - csv를 sqlite로 가져 오는 것이 좋습니다.하지만 파일에 쉼표가있는 것으로 나타납니다 (예 : "My title, comma"). 가져 오기에 오류가 발생했습니다.

다른 생각 ... 파일을 수동으로 편집하는 사건의 너무 많은가 나타납니다 ?? **

+1

큰 파일입니다. 얼마나 시간이 걸려요? – Blender

+0

몇 개의 중복 레코드가 있습니까? 많은 경우 이미 삽입 된 레코드의 로컬'set '을 유지하고 중복에 대해 SQL 호출을 건너 뛰는 것이 더 빠를 것입니다. – kindall

+0

[여기] (http://dev.mysql.com/doc/refman/5.5/en/insert-speed.html)은 MySQL 대량로드 속도 팁입니다. – kindall

답변

24

그것은 직접적으로 CSV를 가져올 수있다 :

sqlite> .separator "," 
sqlite> .import filecsv.txt mytable 

http://www.sqlite.org/cvstrac/wiki?p=ImportingFiles

+1

"blah blah, blah", "123"이 문제를 일으 킵니다.이 문제는 무엇입니까? – user735304

+0

기본으로 탈출 할 수있는 기본 방법이없는 것처럼 보입니다. 또한 따옴표는 문자열 내의 리터럴이됩니다. CSV 구문 분석을 사용하여 텍스트를 변경하고 다른 구분 기호로 출력하는 것은 이치에 맞지만 가져 오기 도구를 처음 사용하는 목적을 상쇄 할 수 있습니다. – fengb

+0

시도해보십시오. .separator 대신 .mode csv를 참조하십시오. http://stackoverflow.com/questions/14947916/import-csv-to-sqlite/24582022#24582022 – NumesSanguis

3

거래를 사용해보십시오.

begin  
insert 50,000 rows  
commit 

이는 행당 한 번이 아니라 주기적으로 데이터를 커밋합니다.

20

Chris은 오른쪽 사용 트랜잭션입니다. 데이터를 청크로 나누어 저장하십시오.

""트랜잭션이없는 한 각 SQL 문에는 새로운 트랜잭션이 시작됩니다.이 문은 각 문에 대해 저널 파일을 다시 열고, 쓰고 닫아야하기 때문에 매우 비쌉니다. 트랜잭션을 BEGIN과 SQL 문 시퀀스를 포장하여 피할 수, 그리고 최종 TRANSACTION; 문이 속도 향상은 또한 데이터베이스를 변경하지 않는 문에 대해 얻을 수있다 "- 자료 : http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

는"이 ...있다.. 또 다른 트릭을 사용하여 SQLite : 트랜잭션을 가속화 할 수 있습니다. 여러 데이터베이스 쓰기를 수행해야 할 때마다 트랜잭션 내부에 저장하십시오. 쓰기 쿼리가 발행되면 트랜잭션 완료시에만 쓰기가 발생합니다. "- 자료 : How Scalable is SQLite?

import csv, sqlite3, time 

def chunks(data, rows=10000): 
    """ Divides the data into 10000 rows each """ 

    for i in xrange(0, len(data), rows): 
     yield data[i:i+rows] 


if __name__ == "__main__": 

    t = time.time() 

    conn = sqlite3.connect("path/to/file.db") 
    conn.text_factory = str #bugger 8-bit bytestrings 
    cur = conn.cur() 
    cur.execute('CREATE TABLE IF NOT EXISTS mytable (field2 VARCHAR, field4 VARCHAR)') 

    csvData = csv.reader(open(filecsv.txt, "rb")) 

    divData = chunks(csvData) # divide into 10000 rows each 

    for chunk in divData: 
     cur.execute('BEGIN TRANSACTION') 

     for field1, field2, field3, field4, field5 in chunk: 
      cur.execute('INSERT OR IGNORE INTO mytable (field2, field4) VALUES (?,?)', (field2, field4)) 

     cur.execute('COMMIT') 

    print "\n Time Taken: %.3f sec" % (time.time()-t) 
+0

이 코드를 따르는 다른 사용자가 사용하려고 시도한 문제가 발생했습니다. 'len()'을 CSV 리더와 함께 사용하면됩니다. http://stackoverflow.com/questions/18062694/sqlite-transaction-for-csv-importing/18063276#18063276 – rutter

14

는 트랜잭션이 많은 삽입 성능을 향상 할, (크리스 샘) 말한 것으로

, 나, 또 다른 옵션을 사용하는 것이 좋습니다 파이썬 유틸리티 모음을 사용하여 주시기 바랍니다. CSV, csvkit와 함께 작동하는

를 설치하려면 :.

pip install csvkit 

이 문제를 해결하기 위해

csvsql --db sqlite:///path/to/file.db --insert --table mytable filecsv.txt 
관련 문제