Datenbank Eintrag

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Sokrates19
User
Beiträge: 7
Registriert: Mittwoch 13. Januar 2021, 19:27

Hallo,
ich versuche gerade herauszufinden ob zu einem mit tkinter eingegebenen Primay Key in meiner Datenbank(sqlite3) ein passender Eintrag existiert. Wie kann ich das herausfinden? /c

Code: Alles auswählen

kartennr = str(Nummer.get())
    sql = 'SELECT kartennummer FROM personen WHERE kartennummer = ? '
    cursor.execute(sql, (kartennr,))
    for dsatz in cursor:
        kartennr = int(kartennr)
        Key = dsatz[0]
        if Key == kartennr :
           	tkinter.messagebox.showerror("Error","Nutzer existiert bereits")
        else:
    		popup = tkinter.Toplevel(main)
   		 sql = "INSERT INTO personen VALUES('Name', " \
    		"'Nachname',?, 0)"
   		 cursor.execute(sql, (kartennr,))
    		Vorname = tkinter.Label(popup, text="Vorname")
    		Vorname.pack()
    		Name = tkinter.Entry(popup)
    		Name.pack()

    		Zuname = tkinter.Label(popup, text="Nachname")
    		Zuname.pack()
    		Nachname = tkinter.Entry(popup)
    		Nachname.pack()
  		 nn = str(Nachname.get())
    		sql = "UPDATE personen SET Name = ? WHERE kartennummer =" +str(kartennr)
    		cursor.execute(sql, (nn, ))
So habe ich das Versucht. jedoch funktioniert es nicht. kann mir jemand sagen wie ich das lösen kann? Ich bin was den Bereich Datenbanken und dazugehörige Abfragen noch Neuling.
Danke schonmal im Vorraus
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingerückt wird immer mit 4 Leerzeichen pro Ebene, keine Tabs.
Variablennamen werden komplett klein geschrieben.
Benutze keine kryptischen Abkürzungen, dsatz? gibt es auch einen asatz?
Warum wandelst Du die Kartennummer erst in einen String und dann in ein int um? Die Kartennummer sollte doch immer eine Zahl sein.
Die Kartennummer sollte doch eindeutig sein, eine for-Schleife ist da Unsinn. Man benutzt fetchone, um einen Datensatz zu bekommen. Wenn die SQL-Abfrage korrekt ist, dann ist Key immer gleich der Kartennummer.
Existiert keine Kartennummer, dann wird die for-Schleife nie betreten.
Dann fügt man in eine Datenbank keinen Eintrag mit Dummy-Werten ein, sondern gleich die richtigen Daten. Wenn kartennummer als ›unique‹ definiert ist, dann wird automatisch ein Fehler geworfen, so dass die ganze Überprüfung am Anfang unnötig ist.
kartennummer sollte nicht der Primary Key sein, sondern man benutzt als ID etwas, was wirklich nur Datenbankintern benutzt wird.
Datenbankabfragen und GUI sollten nicht gemischt werden, sondern die Datenbankabfrage in eigene Funktionen (oder einer Klasse) ausgelagert werden.

Nicht alles muß an einen Namen gebunden werden, z.B. die ganzen Labels, die nie wieder gebraucht werden.
Zu dem Zeitpunkt, wo Du Nachname.get aufrufst, hatte der Nutzer das Fenster noch gar nicht gesehen, kann also noch gar nichts eingegeben haben.
Benutzeravatar
Sokrates19
User
Beiträge: 7
Registriert: Mittwoch 13. Januar 2021, 19:27

Erstmal danke für die Antwort, aber ich verstehe ein paar Sachen nicht. Erstens wie soll ich in einen SQL-Befehl der über execute ausgeführt wird bitteschön 3 Variablen gleichzeitig einfügen? Ich kann mit cursor.execute nur nach SQL nurnoch eine Variablen einfügen. da muss ich ja dann zuerst den Dummy einfügen und den dann mit den Eingaben aus dem popup updaten. Zweitens ich habe es über fetchone versucht, warscheinlich hab ich da was in der Syntax verkackt, wie wäre da die richtige?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie kommst du darauf, dass du nur eine Variable angeben kannst? Siehe zb https://stackoverflow.com/questions/902 ... -in-python
Benutzeravatar
Sokrates19
User
Beiträge: 7
Registriert: Mittwoch 13. Januar 2021, 19:27

OK, in der Variante geht es, ich halte mich derzeit noch etwas strenger an das Buch "Einstig in Python" von Thoma Theis, und wenn ich den dortigen Beispielen folge definiere ich den SQL Befehl zuerst als string und gebe den dann in .execute, dadurch muss ich in dem string Variablen mit? angeben, dadurch kann ich dann in execute nur noch eine variable einfügen : cursor.execute(sql, (x,)) ist dann das was ich zum ausführen verwende
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist doch Unsinn. Du kannst auch hundert ? angeben, und dann eben hundert Argumente mit dem Tuple abliefern. Oder wie hier gefordert eben 3. Warum darf das nur eines sein? Nur weil das in deinem Buch steht? Ist der Code oben auch so im Buch? Wenn nicht, was hat dich dazu bewogen, vom geheiligten Skript abzuweichen? Und wenn du das *da* konntest, warum nicht beim SQL?
Benutzeravatar
Sokrates19
User
Beiträge: 7
Registriert: Mittwoch 13. Januar 2021, 19:27

Hier ist ein Beispiel bei welchem ich mich, mit Ausnahme der weiteren Variable, an das Skript im Buch gehalten habe.
import tkinter
import sqlite3
connection = sqlite3.connect("Betrag.db")
cursor = connection.cursor()
y=0
x=9188664
sql= "UPDATE personen SET betrag = ?" \
"WHERE kartennummer = ? "
cursor.execute(sql, (y, ),(x,))

und das die dazugehörige Fehlermeldung:Traceback (most recent call last):
File "I:\Neues Textdokument.py", line 9, in <module>
cursor.execute(sql, (y, ),(x,))
TypeError: function takes at most 2 arguments (3 given)
>>>
Benutzeravatar
Sokrates19
User
Beiträge: 7
Registriert: Mittwoch 13. Januar 2021, 19:27

Ist jetzt aber auch egal , wir driften hier glaube ich etwas vom eigentlichen Thema ab und wenn ich ehrlich bin will ich jetzt auch nicht hier irgendeinen streit anfangen. Ihr du hast definitiv mehr Ahnung davon als ich, also gehe ich mal davon aus das ich irgendetwas übersehen oder falsch gemacht habe weshalb es nicht geht. Das eigentliche Problem konnte ich dank Sirius lösen, danke an der Stelle nochmal für die Hilfe, und darum will ich jetzt auch nicht irgendwie noch nen Streit/ne weitere Diskussion vom Zaun brechen vor allem da das Programm jetzt genau so funktioniert wie es soll, auch wenn ich vlt bei dem ein oder Anderen Befehl was hätte abkürzen können.
einfachTobi
User
Beiträge: 491
Registriert: Mittwoch 13. November 2019, 08:38

Der Fehler sagt dir, dass die Funktion max. 2 Argumente erwartet, du ihr aber 3 übergibst: sql, (y,) und (x,). Wenn du x ebenfalls übergeben willst, musst du das ein *einem* Tupel machen: execute(sql, (y, x, z, weitere_variable)).

Das hat nix mit Streit zu tun. Ich glaube du hast einfach noch nicht verstanden, was es mit den Klammern auf sich hat. Was ja kein Problem ist, weil du dabei bist es zu lernen. Am besten noch mal das Kapitel zu Datenstrukturen (Tuple, List, Dict, ...) lesen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

execute erwartet ein Tuple für Parameter, Du hast zwei übergeben.
Tuple sind so etwas grundlegendes, da wundert es manche, wie man mit GUIs anfangen kann, ohne das gut zu beherrschen.

Code: Alles auswählen

cursor.execute("UPDATE personen SET betrag = ?"
    "WHERE kartennummer = ?", (y, x))
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

zur Ausgangfrage: zu SQLite und Python gibt es in der offiziellen Python-Doku ein komplettes Kapitel - hast du das schon mal gelesen?

Das Vorgehen ist normalerweise so:
* SQL-Statement bauen
* SQL-Statement ausführen, Ergebnis abholen und an eine Variable binden
* Variable prüfen - wenn die nichts enthält gibt es den PK nicht

Gruß, noisefloor
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

Sokrates19 hat geschrieben: Sonntag 13. Juni 2021, 14:36 Ist jetzt aber auch egal , wir driften hier glaube ich etwas vom eigentlichen Thema ab [...]
Lieber Sokrates, ich... mache das nicht gerne, muß aber leider trotzdem nochmal ein bisschen abdriften.

Leider (oder zum Glück?) kenne ich Dein Lehrbuch nicht, aber ich... sehe, wie Du vorgehst. Anscheinend hast Du eine Idee für eine Software, Dir eine passende Programmiersprache ausgesucht, bist erfreulicherweise bei Python gelandet, hast Dir ein Buch zugelegt und es zumindest teilweise durchgearbeitet. Bis hierher ist das eine super Idee, alles richtig gemacht, herzlichen Glückwunsch!

Aber dann hast Du anscheinend leider viel zu schnell an Dein Projekt gedacht und versuchst jetzt, einen Schritt zu machen, ohne die vorherigen, zwingend notwendigen Schritte vollzogen zu haben. Du versuchst gerade, das Dach Deines Hauses zu bauen, bevor die Fundamente ausgehärtet und die Wände gebaut sind. Deswegen kommst Du auf Ideen wie

Code: Alles auswählen

cursor.execute(sql, (y, ),(x,))
ohne darüber nachzudenken, was diese Klammern und die Kommata da machen. So

Code: Alles auswählen

cursor.execute(sql, (y,  x))
hätte es funktioniert, und so

Code: Alles auswählen

cursor.execute(sql, [y,  x])
vermutlich auch. Also bitte konsultiere Dein Lehrbuch noch einmal, was der Unterschied zwischen () und [] ist und was ein tuple() von einer list() unterscheidet... Viel Erfolg!
Antworten