2015-02-19 13 views
5

Ho impostato un database sqlite3. L'ho riempito con alcuni dati (~ 4 milioni di record ~ ​​1.2 GB di dati). Quindi eseguo alcune query (seleziona/elimina/aggiorna). Il problema è che a volte dopo gli inserimenti lo script si ferma senza errori. A volte funziona normalmente fino alla fine. Queste sono il tipo di query corro:sqlite3 python inaspettata terminazione

from __future__ import print_function 
import sqlite3 
import csv 
import os 
import glob 
import sys 
import time 

db = 'test.db' 

conn = sqlite3.connect(db) 
conn.text_factory = str # allows utf-8 data to be stored 

c = conn.cursor() 
i = 0 
### traverse the directory and process each .csv file 

##print("debug") 
csvfile =('/home/Desktop/Untitled Folder/Crimes_-_2001_to_present.csv') 
with open(csvfile, "rb") as f: 
    reader = csv.reader(f) 
    t = time.time() 
    header = True 
    for row in reader: 
     if header: 
      # gather column names from the first row of the csv 
      header = False 

      sql = "DROP TABLE IF EXISTS test_table" 
      c.execute(sql) 
      #print("debug 1") 
      sql = "CREATE TABLE test_table (ID INTEGER,FBI_Code INTEGER,Updated_On TEXT,District TEXT,Beat INTEGER,Primary_Type TEXT,Location BLOB,Latitude REAL,Arrest INTEGER,Domestic INTEGER,Longitude REAL,Community_Area INTEGER,Case_Number INTEGER,Block TEXT,Location_Description TEXT,Ward INTEGER,IUCR INTEGER,Year INTEGER, Date TEXT,Y_Coordinate INTEGER,Description TEXT,X_Coordinate INTEGER);" 
      c.execute(sql) 
      #print("debug 2") 
      insertsql = "INSERT INTO test_table VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" 
      rowlen = len(row) 
      #print("debug 3") 
     else: 
      # skip lines that don't have the right number of columns 
      #print("debug 4") 
      #if len(row) == rowlen: 
       #print("debug 5") 
      try: 
       c.execute(insertsql, row) 
      except: 
       print("problem in row %d" % i) 
       print(row) 
       continue 

      # print("debug 6") 
      i +=1 
      if i == 1000: 
       conn.commit() 
####   if i == 4000000: 
####    break 
##   #print (row) 
conn.commit() 

print('\nTime for Insertions TOTAL~> \n') 
print(float(time.time() -t)) 

print('\nTime for Insertions per Query~> \n') 
print(float(time.time() -t)/i) 
del rows 
rows = list() 

print('\nTime for Selections ~> Domestic\n') 
t = time.time() 
c.execute("SELECT * FROM test_table WHERE Domestic == 'false'") 
rows = c.fetchall() 
print(float(time.time() -t)) 
print(len(rows)) 
del rows 
rows = list() 

print('\nTime for Selections ~> Arrests\n') 
t = time.time() 
c.execute("SELECT * FROM test_table WHERE Arrest == 'false'") 
rows = c.fetchall() 
print(float(time.time() -t)) 
print(len(rows)) 
del rows 
rows = list() 

print('\nTime for Selections ID~> \n') 
t = time.time() 
c.execute("SELECT * FROM test_table WHERE ID < 9938614") 
rows = c.fetchall() 
print(float(time.time() -t)) 
print(len(rows)) 
del rows 
rows = list() 

print('\nTime for Selections ~> Primary_Type\n') 
t = time.time() 
c.execute("SELECT * FROM test_table WHERE Primary_Type == 'BATTERY'") 
rows = c.fetchall() 
print(float(time.time() -t)) 
print(len(rows)) 
del rows 
rows = list() 

print('\nTime for Selections Year~> \n') 
t = time.time() 
c.execute("SELECT * FROM test_table WHERE Year <= 2014") 
rows = c.fetchall() 
print(float(time.time() -t)) 
print(len(rows)) 
del rows 
rows = [] 

print('\nTime for Updates ~> YEAR\n') 
t = time.time() 
c.execute("UPDATE test_table SET Year = '2016' WHERE Year == '2014'") 
print(float(time.time() -t)) 

print('\nTime for Selections Year~> \n') 
t = time.time() 
c.execute("SELECT * FROM test_table WHERE Year <= 2014") 
rows = c.fetchall() 
print(float(time.time() -t)) 
print(len(rows)) 

print('\nTime for DELETIONS ~> Domestic\n') 
t = time.time() 
c.execute("DELETE FROM test_table WHERE Domestic == 'false'") 
rows = c.fetchall() 
print(float(time.time() -t)) 
print(len(rows)) 
del rows 

c.close() 
conn.close() 

Ogni volta che riassegnare la lista fila perché dopo alcune query ho esaurito la memoria. Ma non penso che sia questo il problema (nel caso in cui ho usato del file & riassegnato, è stato più lento in quel modo). Comunque dopo alcune di queste query lo script si interrompe senza errori e non riesco a capire perché, perché ci sono alcune volte in cui gira OK.

Modifica

Ho compreso il codice di cui sopra. Il problema è che dopo la parte di inserimento quando faccio le query lo script è terminato senza errori.

Per esempio si va fino a qui:

... Tempo per le selezioni ~> Arresti

123,231

e poi termina. Nel primo approccio non ho cancellato la lista e Cython ha prodotto errori di dump di core quando ho provato a ripetere la lista. Ora che cancello e dichiaro la lista, Cython gira ok. La mia domanda è: perché Python non rileva alcuna eccezione?

Dopo la riassegnazione dell'elenco, Garbage Collector cancella i dati del cestino (e lo fa, come ho visto dal monitor Linux) ma si blocca senza errori. E il più fastidioso è che a volte va bene fino alla fine.

+0

Se esce in modo imprevisto senza errori (o si blocca), è possibile aggiungere le istruzioni 'print' per vedere fino a che punto si ferma. – glglgl

+0

ogni query prima che venga eseguita ha un'istruzione di stampa, quindi so in quale query sono. Ma quando si arresta/si blocca, non è la stessa query del crash precedente. –

+0

Ho anche provato a riassegnare l'elenco delle righe come, row = list(), ma continua ad arrestarsi in modo anomalo senza uscire da un errore. A volte è alle prime 2-3 query e talvolta alla fine delle query. –

risposta

0

Ho avuto esattamente lo stesso problema, la mia soluzione era quella di creare un nuovo cursore, quindi ho gestito SQL Select con un cursore e inserisce/elimina con l'altro.

conn = sqlite3.connect(db) 
c = conn.cursor() 
c2 = conn.cursor()