2013-02-25 2 views
0

CSV에서 값을 가져 와서 데이터베이스에 넣으려고합니다. 큰 문제없이이 작업을 처리하고 있습니다.Python CSV를 읽고 MySQL 데이터베이스에 값을 넣으십시오.

하지만 csv에 다시 쓸 필요가 있으므로 다음에 스크립트를 실행하면 csv 파일의 표시에서 DB로만 값을 입력합니다.

시스템의 CSV 파일은 매 24 시간마다 자동으로 플러시되므로 csv에 마르크가 표시되지 않을 수 있습니다. 그래서 기본적으로 모든 값을 데이터베이스에 넣습니다.

나는이 스크립트를 매 30 분마다 실행할 계획이므로 csv 파일에 48 자국이 있거나 심지어는 그 표식을 제거하고 매번 파일 아래로 옮길 수 있습니까?

파일을 삭제 한 다음 스크립트에서 파일을 다시 작성하면 모든 스크립트가 실행될 때마다 새 파일이 실행되지만 시스템에 아무런 문제가 없으므로 훌륭한 옵션이 아닙니다.

import csv 
import MySQLdb 

mydb = MySQLdb.connect(host='localhost', 
user='root', 
passwd='******', 
db='kestrel_keep') 

cursor = mydb.cursor() 

csv_data = csv.reader(file('data_csv.log')) 

for row in csv_data: 

    cursor.execute('INSERT INTO `heating` VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,)', 
    row) 
#close the connection to the database. 
mydb.commit() 
cursor.close() 
import os 


print "Done" 

내 CSV 파일 형식 :

희망 너희들이 도움이 될 수 있습니다

..

당신에게

파이썬 코드 감사

2013-02-21,21:42:00,-1.0,45.8,27.6,17.3,14.1,22.3,21.1,1,1,2,2 
2013-02-21,21:48:00,-1.0,45.8,27.5,17.3,13.9,22.3,20.9,1,1,2,2 

답변

1

내가 생각하는 더 나은 옵션보다 CSV 파일을 "표시"하는 것은 마지막으로 처리 한 행의 번호를 저장 한 파일을 유지하는 것입니다.

파일이 없으면 (마지막으로 처리 된 행의 번호를 저장 했음) 전체 CSV 파일을 처리합니다. 이 파일이 있으면이 행 다음의 레코드 만 처리합니다.

최종 코드에서 작업 시스템 :

#!/usr/bin/python 
import csv 
import MySQLdb 
import os 

mydb = MySQLdb.connect(host='localhost', 
user='root', 
passwd='*******', 
db='kestrel_keep') 

cursor = mydb.cursor() 

csv_data = csv.reader(file('data_csv.log')) 

start_row = 0 

def getSize(fileobject): 
fileobject.seek(0,2) # move the cursor to the end of the file 
size = fileobject.tell() 
return size 

file = open('data_csv.log', 'rb') 
curr_file_size = getSize(file) 

# Get the last file Size 
if os.path.exists("file_size"): 
with open("file_size") as f: 
    saved_file_size = int(f.read()) 


# Get the last processed line 
if os.path.exists("lastline"): 
with open("lastline") as f: 
    start_row = int(f.read()) 


if curr_file_size < saved_file_size: start_row = 0 

cur_row = 0 
for row in csv_data: 
if cur_row >= start_row: 
    cursor.execute('INSERT INTO `heating` VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ,%s)', row) 

    # Other processing if necessary 

cur_row += 1 

mydb.commit() 
cursor.close() 


# Store the last processed line 
with open("lastline", 'w') as f: 
start_line = f.write(str(cur_row + 1)) # you want to start at the **next** line 
             # next time 
# Store Current File Size To Find File Flush  
with open("file_size", 'w') as f: 
start_line = f.write(str(curr_file_size)) 

# not necessary but good for debug 
print (str(cur_row)) 



print "Done" 

편집 : 최종 코드를 ZeroG의에 의해 Submited 현재 시스템에서 작업! 감사합니다. Xion345도 도움을 청합니다.

+0

나는이 답변을 좋아하지만 행을 가져올 수 없다. 우리는 심지어 lastline 파일에 0을 넣고있다 '(str (cur_row))'는 0을 되풀이한다. 파일이 00:01에 플러시 될 때 염두에 두어야한다. 00 라인은 새로운 csv 파일과 관련이 없으므로 어딘가에 시간을 확인해야한다고 가정합니다. – ZeroG

+0

예, 코드가 잘못 됐습니다. 끝에있는'cur_row + = 1' 문을 이동해야합니다. for 루프. 00:01의 플러시에 관해서는 lastline 파일의 현재 시간과 쓰기 날짜를 확인해야합니다. – Xion345

+0

@ZeroG : 파일이 플러시되었는지 감지하는 더 좋은 방법은 CSV 파일의 크기를 마지막 처리 된 줄 외에 마지막 줄 파일에 저장하는 것입니다. 파일을 두 번 연속 실행하면 파일 크기가 감소하면 CSV 파일이 삭제되었음을 알 수 있습니다. – Xion345

1

각 csv 행에는 타임 스탬프가있는 것으로 보입니다. 이들이 항상 증가하고 있다면, 이미 기록 된 최대 타임 스탬프에 대해 db를 질의 할 수 있고, csv를 읽을 때 그 전에 모든 행을 건너 뛸 수 있습니다.

2

MySQL 테이블의 첫 번째 필드는 입니다. 타임 스탬프입니다. 필드가 유일해야하고 고유성 속성을 위반하는 INSERT을 무시하도록 MySQL 테이블을 설정할 수 있습니다.

ALTER IGNORE TABLE heating ADD UNIQUE heatingidx (thedate, thetime)  

(변경 날짜와 시간을 유지하는 열 이름에 thedatethetime하십시오 mysql> 프롬프트에서 다음 명령을 입력합니다.)


당신이 당신의 데이터베이스에이 변경되면, 당신은 단지 MySQL이 중복 삽입 무시 확인하기 위해 프로그램에서 한 줄을 변경해야

cursor.execute('INSERT IGNORE INTO `heating` VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,)', row) 

예, 그것은 조금 이미 처리 된 행에 INSERT IGNORE ...을 실행하는 데 낭비가 있지만 데이터의 빈도가 주어지면 (매 6 분마다) 성능면에서별로 중요하지 않습니다.

이렇게하면 테이블에 실수로 중복을 삽입 할 수 없게됩니다. 또한 프로그램의 논리를 간단하고 읽기 쉽게 유지합니다.

동시에 두 개의 프로그램이 동일한 CSV 파일에 기록하는 것을 방지합니다. 프로그램 이 보통 인 경우에도 오류없이 성공합니다. 파란색 달에 한 번씩 - 프로그램과 다른 프로그램이 동시에 파일에 쓸 수 있기 때문에 오류가 발생하거나 맹 글링이 발생할 수 있습니다 데이터.


또한 cursor.executemany 대신 cursor.execute를 사용하여 좀 더 빠르게 프로그램을 만들 수는 :

rows = list(csv_data) 
cursor.executemany('''INSERT IGNORE INTO `heating` VALUES 
    (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,)''', rows) 

가 하나의 명령으로 모든 데이터를 팩 것을 제외하고

for row in csv_data:  
    cursor.execute('INSERT INTO `heating` VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,)', 
    row) 

에 해당합니다 .

+0

내가 좋아하지만 날짜와 시간이 두 개의 별도 필드입니까 ??? – ZeroG

+0

@ ZeroG : 그건 문제가되지 않습니다. 고유 한 행을 정의하는 데 필요한 모든 필드를 나열하십시오.위의 게시물을 편집하여 내 뜻을 보여줍니다. – unutbu

+0

이것은 날짜와 시간이 다를 필요가 있음을 고려합니다. 즉, 날짜가 다를지라도 2 일 안에 14시 2 분이 있습니까? – ZeroG

관련 문제