sqlite Datensatz Update

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Welpe
User
Beiträge: 17
Registriert: Mittwoch 30. Dezember 2020, 10:39

Samstag 20. November 2021, 14:34

Moin, ich habe mit PyQT5 eine GUI erstellt um damit auf eine sqlite Datenbank zuzugreifen. Unter Linux funktioniert das hervorragend, unter Windows leider nicht. Ich führe den Code bei beiden OS direkt in VSCode aus.

Code: Alles auswählen

# Neuen Datensatz speichern, funktioniert auf beiden Betriebssystemen

conn = sqlite3.connect('data.db')
cur = conn.cursor()
insert_data = '''INSERT INTO zugangsdaten(zugang,benutzername,passwort,user)VALUES(?,?,?,?)'''
cur.execute(insert_data, [(self.ety_zugang.text()),(self.ety_benutzername.text()),(self.ety_passwort.text()),(self.user)])
conn.commit()

Code: Alles auswählen

# Alle Datensätze des eingeloggten Users auslesen, funktioniert auf beiden Betriebssystemen

conn = sqlite3.connect('data.db')
cur = conn.cursor()
sqlquery = 'SELECT zugang, benutzername, passwort, rowid FROM zugangsdaten WHERE user = ?'
cur.execute(sqlquery, [self.user])
daten = cur.fetchall()

Code: Alles auswählen

# Datensatz nach der Bearbeitung wieder in die Datenbank speichern, funktioniert nur unter Linux

conn = sqlite3.connect('data.db')
cur = conn.cursor()
update_data = 'UPDATE zugangsdaten SET zugang = ?, benutzername = ?, passwort = ? WHERE rowid = ?'
cur.execute(update_data, [self.ety_zugang.text(), self.ety_benutzername.text(), self.ety_passwort.text(), self.lbl_rowid.text()])
 conn.commit()
Unter Windows 10 funktioniert das updaten des Datensatzes leider nicht, keine Fehlermeldung und die alten Daten bleiben erhalten. Ich habe auch schon verschiedene Schreibweisen in der cur.execute probiert. Unter Linux funktionieren alle, unter Windows keine ... Hat jemand eine Idee?
Benutzeravatar
__blackjack__
User
Beiträge: 9472
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Samstag 20. November 2021, 15:41

@Welpe: Da ist auf jeden Fall mal ein Syntaxfehler drin, weil die letzte Zeile falsch eingerückt ist.

`ety` und `lbl`? Das sollte man weder mit drei Buchstaben abkürzen, und wenn man nicht Yoda heisst, auch nach hinten verschieben. Denn ein `entry_passwort` ist etwas anderes als ein `passwort_entry`.

Code: Alles auswählen

loop_:  cmp     byte [asleep],0
        jne     return
        inc     dword [sheep]
        jmp     loop_
return: ret
Welpe
User
Beiträge: 17
Registriert: Mittwoch 30. Dezember 2020, 10:39

Sonntag 21. November 2021, 12:58

Hallo __blackjack__

Der Syntaxfehler mit der Einrückung ist beim kopieren des Codes hierhin entstanden. Das habe ich vor dem abschicken übersehen, Sorry. In meinem Script ist der nicht vorhanden.

Die drei Buchstaben stehen für entry und label. Ich schreibe das halt davor um zu wissen um was für ein Feld es sich handelt.

Was bedeutet der Code, den Du gepostet hast?
__deets__
User
Beiträge: 10711
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 21. November 2021, 13:41

Das ist kein gelisteter Code, sondern __blackjack__s Signatur. Ein Assembler-Programm zum Schäfchenzählen.

Bezüglich deines Problems: ich sehe keinen Grund aus Sicht des Programms, warum es nicht klappen sollte. Also vermute ich einen Benutzerfehler. Wie stellst du denn fest, dass es nicht geklappt hat? Eine Vermutung: der Pfad ist relativ, und du öffnest darum unterschiedliche Datenbanken.
Benutzeravatar
sparrow
User
Beiträge: 2880
Registriert: Freitag 17. April 2009, 10:28

Sonntag 21. November 2021, 14:00

Oder der entsprechende Datensatz existiert gar nicht in der Datenbank.
Also self.lbl_rowid.text() ist nicht, was du denkst, dass es ist.
Wenn du vorher ein SELECT mit der Klausel machst, solltest du ja sehen, ob der Datensatz überhaupt vorhanden ist.
Welpe
User
Beiträge: 17
Registriert: Mittwoch 30. Dezember 2020, 10:39

Montag 22. November 2021, 06:37

Danke Euch für die Hinweise, ich habe nochmal alles durchgewühlt und den Fehler gefunden. Es liegt nicht an der Abfrage sondern wie ich da hin komme. Ich benutze die Messagebox in PyQT5 um den Benutzer zu fragen, ob er den Datensatz wirklich überschreiben möchte. Die Buttons (OK + CANCEL) in der Messagebox geben einen String zurück, welchen ich abfrage um zu wissen, welcher Button gedrückt wurde. PyQT5 gibt beim drücken des OK-Buttons unter Linux ein "&OK" zurück, unter Windows allerdings nur "OK". Somit wurde die Funktion unter Windows gar nicht aufgerufen.

Hier nochmal die betreffende Funktion

Code: Alles auswählen

    def aktualisieren(self):
        if self.ety_zugang.text() == '' or self.ety_benutzername.text() == '' or self.ety_passwort.text() == '':
            msg = QtWidgets.QMessageBox()
            msg.setWindowTitle('Eingabe unvollständig!')
            msg.setText('Bitte alle Felder ausfüllen.')
            msg.setStyleSheet('background-color: rgb(60, 60, 60); color:rgb(208, 208, 208);')
            msg.setIcon(QtWidgets.QMessageBox.Critical)
            x = msg.exec()
        elif self.lbl_rowid.text() == '':
            msg = QtWidgets.QMessageBox()
            msg.setWindowTitle('Aktualisieren nicht möglich!')
            msg.setText('Datensatz ist noch nicht vorhanden.')
            msg.setInformativeText('Bitte erst den neuen Datensatz speichern.')
            msg.setStyleSheet('background-color: rgb(60, 60, 60); color:rgb(208, 208, 208);')
            msg.setIcon(QtWidgets.QMessageBox.Critical)
            x = msg.exec()
        else:
            def ok_button(i):
                if i.text() == '&OK': # <-- hier ist das Problem
                    conn = sqlite3.connect('data.db')
                    cur = conn.cursor()
                    update_data = 'UPDATE zugangsdaten SET zugang = ?, benutzername = ?, passwort = ? WHERE rowid = ?'
                    cur.execute(update_data, [self.ety_zugang.text(), self.ety_benutzername.text(), self.ety_passwort.text(), self.lbl_rowid.text()])
                    conn.commit()
                    self.db_laden_alles()
                    self.eingabefelder_leeren()

            msg = QtWidgets.QMessageBox()
            msg.setWindowTitle('Bitte bestätigen!')
            msg.setText('Zugangsdaten überschreiben?')
            msg.setStyleSheet('background-color: rgb(60, 60, 60); color:rgb(208, 208, 208);')
            msg.setIcon(QtWidgets.QMessageBox.Warning)
            msg.setStandardButtons(QtWidgets.QMessageBox.Ok|QtWidgets.QMessageBox.Cancel)
            msg.setDefaultButton(QtWidgets.QMessageBox.Ok)
            msg.buttonClicked.connect(ok_button)
            x = msg.exec()    
Sirius3
User
Beiträge: 15274
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 22. November 2021, 07:47

Dafür ist der Rückgabewert der exec-Methode da.
Du solltest dringend an der Benennung Deiner Variablen arbeiten. Benutze keine Abkürzungen, wer weiß schon was mit ety gemeint ist?
i für ein widget oder x für den Rückgabewert der MessageBox sind weitere Beispiele, dass ein schlechter Name für Verwirrung sorgt.
Welpe
User
Beiträge: 17
Registriert: Mittwoch 30. Dezember 2020, 10:39

Mittwoch 24. November 2021, 05:32

Ich arbeite dran -.-
Antworten