2017-03-09 3 views
1

Ich habe eine Postgres-Datenbank geerbt und bin gerade dabei, sie zu bereinigen. Ich habe einen Algorithmus zu finden die Zeilen, in denen die Daten schlecht sind. Der Algorithmus ist in der Funktion checkProblems() codiert. Mit dieser, ich bin in der Lage, die Zeilen auszuwählen, die die schlechten Zeilen enthält, wie unten gezeigt ...eine Postgres-Tabelle mit fehlerhaften Zeilen bereinigen

schema = findTables(dbName) 

conn = psycopg2.connect("dbname='%s' user='postgres' host='localhost'"%dbName) 
cur = conn.cursor() 

results = [] 
for t in tqdm(sorted(schema.keys())): 

    n = 0 
    cur.execute('select * from %s'%t) 
    for i, cs in enumerate(tqdm(cur)): 
     if checkProblem(cs): 
      n += 1 

    results.append({ 
     'tableName': t, 
     'totalRows': i+1, 
     'badRows' : n, 
    }) 

cur.close() 
conn.close() 

print pd.DataFrame(results)[['tableName', 'badRows', 'totalRows']] 

Nun, ich muss die Zeilen löschen, die schlecht sind. Ich habe zwei verschiedene Möglichkeiten, dies zu tun. Erstens kann ich die sauberen Zeilen in eine temporäre Tabelle schreiben und die Tabelle umbenennen. Ich denke, dass diese Option zu speicherintensiv ist. Es wäre viel besser, wenn ich nur den spezifischen Datensatz am Cursor löschen könnte. Ist das überhaupt eine Option?

Was ist sonst der beste Weg, einen Datensatz unter solchen Umständen zu löschen? Ich vermute, dass dies eine relativ häufige Sache sein sollte, die Datenbankadministratoren tun ...

Antwort

1

Natürlich löschen Sie den spezifischen Datensatz am Cursor ist besser. Sie können, wie etwas tun:

for i, cs in enumerate(tqdm(cur)): 
    if checkProblem(cs): 
     # if cs is a tuple with cs[0] being the record id. 
     cur.execute('delete from %s where id=%d'%(t, cs[0])) 

Oder Sie können die IDs der schlechten Aufzeichnungen speichern und dann so etwas wie FROM Tabelle DELETE WHERE id IN (ID1, ID2, ID3, ID4)