Richtige Spalte aktualisieren

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
fedjan
User
Beiträge: 14
Registriert: Montag 26. November 2012, 16:12

Hallo,

ich habe ein Problem. ich versuche eine Tabelle up-zu-date-ten. Dafür lese ich erst die Tabellendaten/Attribute ein im Form von einer Liste aus Tupeln:

[('01', 'Key_ADA', '1', 'NOT NULL', 'varchar', 7), ('02', 'Firmenname', '0', 'NOT NULL', 'varchar', 82), ('03', 'Hausnr_von', '0', ' ', 'varchar', 6), ('04', 'Hausnr_von_Zusatz', '0', ' ', 'varchar', 6), ('05', 'Hausnr_bis', '0', ' ', 'varchar', 6), ('06', 'Hausnr_bis_Zusatz', '0', ' ', 'varchar', 6), ('07', 'Land', '0', 'NOT NULL', 'varchar', 5), ('08', 'Ort_Zustellung', '0', ' ', 'varchar', 42), ('09', 'Ort_Postfach', '0', ' ', 'varchar', 42), ('10', 'Postfach', '0', ' ', 'varchar', 12), ('11', 'PLZ_Zustellung', '0', ' ', 'varchar', 12), ('12', 'PLZ_Postfach', '0', ' ', 'varchar', 12), ('13', 'PLZ_Grosskunde', '0', ' ', 'varchar', 12), ('14', 'Sortiername', '0', 'NOT NULL', 'varchar', 42), ('15', 'Strasse', '0', ' ', 'varchar', 42), ('22', 'Firmenname_2', '0', ' ', 'varchar', 42), ('23', 'Firmenname_3', '0', ' ', 'varchar', 42)]

nun habe ich folgenden Skript:

Code: Alles auswählen

while(string.find(line, '00U') < 0) and (string.find(line, '00E') < 0) :
                    line    = infile.readline()
                    keyNr   = (int(line[:2])-1)
                    keyVal  = line[2:]
                    keyVal_D_2 = replace_all(keyVal, ucode)
                    if keyNr != -1:
                        keyName = attribute_koplett[keyNr][attrib_columb]
                        keyName_D_2 =replace_all(keyName, ucode)
                        print keyName_D
                        sqlStatement = ("UPDATE "+m.table_name+" SET " + keyName_D_2 + " = '"+keyVal_D_2.strip()+"' " + sqlStatementWhere)
                        print sqlStatement
                        cur.execute (sqlStatement)

                        con.commit()
in der Zeile: keyName = attribute_koplett[keyNr][attrib_columb] -> attrib_columb ist '1' also 2-te element-Attributenname
hole ich mir den Attributenname aus dieser Liste indem ich keyNr als Index(ElementenNr) nutze.

Soweit alles gut. Das Problem ist aber, dass manche Attribute haben komische ID's:('14', 'Sortiername', '0', 'NOT NULL', 'varchar', 42), ('15', 'Strasse', '0', ' ', 'varchar', 42), ('22', 'Firmenname_2', '0', ' ', 'varchar', 42), ('23', 'Firmenname_3', '0', ' ', 'varchar', 42) -> also 14, 15, 22, 23
deshalb kriege ich einen Fehler: IndexError: list index out of range

ich muss also an dieser Stelle den eingelesenen keyNr erst mit 'attribute_koplett[keyNr][0]' also mit dem ID vergleichen und erst dann diesen Attributtenname übernehmen!!

Wie kann ich denn das machen?????

Danke
Fedjan
Zuletzt geändert von Anonymous am Freitag 14. Dezember 2012, 12:28, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Indem du mit einer for-Schleife über die Liste gehst, und nicht die Indexe direkt anspringst.
BlackJack

@fedjan: Du verwendest hier die falsche Datenstruktur. Das sieht nach einem Fall für ein Wörterbuch aus, also der Datentyp `dict` in Python.

Edit: Und wie im anderen Thema schon gesagt, ist so ein Tupel mit magischen Indexzugriffen auch nicht so schön, weil das zu nicht besonders lesbarem Quelltext führt. OOP hilft hier.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo fedjan,

Du meinst wahrscheinlich nicht

Code: Alles auswählen

string.find(line, '00E') < 0
in Deiner while-Bedingung, sondern

Code: Alles auswählen

line[:3] not in ('00U','00E')
weil er sonst bei jede Zeile, in der der Wert eines Keys 00E entählt, abbricht.

Ich würde die Attribute in ein dict schreiben:

Code: Alles auswählen

keyname_map = dict((attr[0],attr[attrib_spalte]) for attr in attribute_koplett)
Wie im anderen Post schon erwähnt ist es schlechter Stil, Strings mit + zu verketten,
und höchst gefährlich, sql-Statements sein externen Dateien zusammenzubasteln.
Für diesen Fall kennt execute Parameter:

Code: Alles auswählen

cur.execute('UPDATE {table} SET {key} = ? WHERE {cond}'.format(
    table=m.table_name, 
    key=keyName_D_2, 
    cond=' AND '.join('{} = ?'.format(key) for key in sqlWhereKeys)),
    [keyVal]+sqlWhereValues)
Die meisten Deiner Klammern sind überflüssig. Bedingungen in Python klammert man nicht.

Deine while-Schleife ist abenteuerlich, weil line erst geprüft und im nächsten Schritt überschrieben wird.
Was ist wenn line tatsächlich 00U ist? Dann wird die ganze Schleife noch einmal durchlaufen.

Grüße
Sirius
fedjan
User
Beiträge: 14
Registriert: Montag 26. November 2012, 16:12

Hallo Zusammen,

danke an alle. ich bin kurz ausgefallen, jetzt versuche ich aber das ganze mal umzusetzen!!

Grüße
Fedjan
Antworten