Ausgabe in Variable, ohne dass diese überschrieben wird

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
tmfdsm
User
Beiträge: 34
Registriert: Donnerstag 28. Januar 2010, 19:41

Also, ich poste erstmal meinen Code und erkläre danach mein Problem:

Code: Alles auswählen

cursor2 = mysql.cursor()
cursor2.execute("SELECT name FROM eventkalender")
result = cursor2.fetchall()
numrows = int(cursor2.rowcount)

cursor3 = mysql.cursor()
cursor3.execute("SELECT url FROM eventkalender")
result2 = cursor3.fetchall()


zahl = 0



while zahl < numrows:
    url = str(result2[zahl])
    but=Button(root, text=result[zahl], command=lambda:open(url))
    but.pack()
    zahl = zahl + 1
Ich möchte aus meiner Datenbank den Namen und die URL auslesen. Auf dem Button soll dann immer der Name stehen und als URL soll die URL aus der Tabelle ausgelesen werden. Mein Problem besteht dabei aber darin, dass die Variable url jedes mal überschrieben wird, sodass bei jedem Button die URL vom letzen Eintrag in der Datenbank aufgerufen wird. Wie kann ich machen, dass dies nicht der Fall ist?
Es kann auch sein, dass mein Code etwas komplizierter ist als nötig, ich kenne aber keine andere Möglichkeit. Ich hoffe, dass ihr mir helfen könnte.
Danke schon mal im Voraus
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

tmfdsm hat geschrieben:

Code: Alles auswählen

cursor2 = mysql.cursor()
cursor2.execute("SELECT name FROM eventkalender")
result = cursor2.fetchall()
numrows = int(cursor2.rowcount)

cursor3 = mysql.cursor()
cursor3.execute("SELECT url FROM eventkalender")
result2 = cursor3.fetchall()
Gibt es einen Grund dafür nicht mit

Code: Alles auswählen

SELECT name, url FROM eventkalender
zu arbeiten sondern doppelten Aufwand zu treiben?
BlackJack

`numrows`/`rowcount` sollte auch überflüssig sein, denn `result` hat ja eine Länge, die man abfragen kann.

Allerdings nicht sollte, denn die ``while``-Schleife ist auch fehl am Platz. Man kann über das/die Ergebnisse auch direkt iterieren, ohne Index.

Namen durchnummerieren ist ein "code smell". Man sollte nicht den Typ als Namen nehmen, wenn es passendere Bezeichner gibt, die den Inhalt oder die Bedeutung besser wiederspiegeln. Hier zum Beispiel `names` und `urls`. `zahl` ist auch übel.

Man braucht auch nicht für jede Abfrage da einen neuen `Cursor`. Letztendlich reicht Einer der beide Daten auf einmal abfragt -- wie /me ja schon anmerkte -- und eine ``for``-Schleife über das Ergebnis.

Was das angesproche Problem angeht: `url` wird aufgelöst, wenn der Code *ausgeführt* wird, und zu *dem* Zeitpunkt ist die Schleife bereits durchgelaufen und `url` eben an den letzten Wert gebunden, den man da mal zugewiesen hatte.

Du suchst `functools.partial()` um Dir eine Funktion aus `open()` und dem Argument zu basteln.

Mit all den Hinweisen kann man Deinen Quelltext auf das hier eindampfen (ungetestet):

Code: Alles auswählen

cursor = mysql.cursor()
cursor.execute('SELECT name, url FROM eventkalender')
for name, url in cursor.fetchall():
    Button(root, text=name, command=partial(open, url)).pack()
Der Code sieht verdammt nach '*'-Importen aus. Das sollte man auch lassen.
Antworten