2016-10-12 10 views
0

Ich habe nach der Verarbeitung einer XML-Datei ein sehr großes Wörterbuch erstellt, und ich suche aus diesem Wörterbuch extrahieren und Spalten und Werte in meine MySQL-Datenbanktabelle einfügen.Python verschachteltes Wörterbuch mit SQL-Einfügung

Ich bin mit Python 3.

Das Wörterbuch ist verschachtelten; hier ist ein einfaches Beispiel von dem, was ich habe:

d ={'Test1'{'TestID':'first','Dev_Type':'this device','Version':'v1_0','Address':'some Address'} 
    'Test2'{'TestID':'second','Dev_Type':'that device','Version':'v1_0','Address':'other Address'} 
    'Test3'{'TestID','third','Dev_Type':'other device','Version':'v1_0','Address':'another Address'} 
} 

Grund mag ich über jeden Primärschlüssel in diesem Wörterbuch (zB Test1, Test2, Test3) und extrahieren Sie den Sekundärschlüssel als Spaltennamen Tupel und den damit verbundenen seconday iterieren Schlüsselwerte als Werte Tupel, ein bisschen wie folgt aus:

cols = ('TestID','Dev_Type','Version','Address') 
vals = ('first','this device','v1_0','some Address') 

auf über jeden Primärschlüssel Iterieren ich die beiden Tupeln meine mySQL Tabelle mit diesem Befehl fügt:

sql = "INSERT INTO Parameters ({0}) VALUES ({1})".format(', '.join(cols), ', '.join(['%s'] * len(cols))); 
try: 
    cursor.execute(sql, vals) 
except Exception as e: 
    print(e) 
    pass 

Dann wiederholen Sie den Vorgang beim nächsten Primärschlüssel ('Test2').

Ich habe einen ersten Versuch gemacht, haben aber schwer, den Primärschlüssel in diesem Fall codiert:

for k, v in d: 
    #Missing appropriate method here 
    cols = tuple(d['Test1'].keys()) 
    vals = tuple(d['Test1'].values()) 

    sql = "INSERT INTO Parameters ({0}) VALUES ({1})".format(', '.join(cols), ', '.join(['%s'] * len(cols))); 
    try: 
     cursor.execute(sql, vals) 
    except Exception as e: 
     pass 

connection.close() 
return 
+0

Dies ist tangential, aber Sie sollten die Parametersubstitution der Datenbank-API verwenden, um gegen SQL-Injektionen zu schützen: https://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.execute –

+0

Meinten Sie zu Lassen Sie das ':' zwischen den Schlüsseln und Werten in Ihrem Beispiel dict aus? –

Antwort

2

Sie über d.values() laufen kann und die .keys() und .values() Methoden auf den verschachtelten Wörterbücher verwenden, um die Spalten zu erhalten und Werte:

for v in d.values(): 
    cols = v.keys() 
    vals = v.values() 

    sql = "INSERT INTO Parameters ({}) VALUES ({})".format(
     ', '.join(cols), 
     ', '.join(['%s'] * len(cols))); 
    try: 
     cursor.execute(sql, vals) 
    except Exception as e: 
     pass 

Beachten Sie, dass die Diktion in Python 3 dict.keys() und dict.values() Rückkehr Ansichten von Schlüssel und Werte (im Gegensatz zu Listen in Python 2).

+0

Gibt es eine Garantie, dass 'v.values ​​() 'wird immer in der gleichen Reihenfolge wie die Liste der Schlüssel' list (v) 'kommen? Sonst werden Sie die falschen Werte in nicht übereinstimmende Spalten einfügen –

+0

Es gibt (https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects) eine solche Garantie für 'd.keys() 'und' d.values ​​() '. "Liste (d)" wird jedoch nicht erwähnt. –

+0

Ja, das sieht besser aus –

0

Iterieren über ein Wörterbuch iteriert tatsächlich über die Schlüssel. for k in d: entspricht for k in d.keys():. Sie suchen die values oder items Methoden, die tatsächlich den Schlüssel und den Wert als Tupel zurückkehren:

for k, v in d.items(): 
    # k will take the values 'Test1', 'Test2', etc. 
    # v will take the values of the corresponding nested dicts. 

oder

for v in d.values(): 
    # v will take on the values of the nested dicts. 

Ich empfehle items über values da diese Weise unter Verwendung würde man so will einen Verweis darauf haben, welchen Primärschlüssel (Test) Sie verarbeiten. Ich werde hier ein wenig aushelfen und denke, dass Sie das für die nicht-triviale Version Ihres Programms brauchen werden.

Von dort nutzen Sie v wie Sie versuchen, d[...] zu verwenden, denn das ist genau das, was es ist:

for k, v in d.items(): 
    cols = v.keys() 
    vals = v.values() 

    sql = "INSERT INTO Parameters ({0}) VALUES ({1})".format(
       ', '.join(cols), 
       ', '.join(['%s'] * len(v)) 
    ) 

    try: 
     cursor.execute(sql, vals) 
    except Exception as e: 
     pass 

connection.close() 
return 

Da v eine verschachtelte Wörterbuch ist, können Sie die Anzahl der Elemente in beiden cols bekommen und vals als nur len(v).

Verwandte Themen