Bestimmte sqlite3-Error's mit except abfangen

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
Tom69
User
Beiträge: 4
Registriert: Freitag 27. Januar 2017, 09:54

Hallo,

ich verwalte meine Daten in eine sqllite-Datenbank, funktioniert soweit auch alles.
Ich möchte meinen Code jetzt mit try und except gegen Abstürze absichern.
Mit except, ohne Attribute, wird bei allgemeinen Errors ausgeführt.

Welche Attribute für den Befehl except stehen mir bei sqlite zur Verfügung?
Für mysql habe ich diesen Ausdruck gefunden: [codebox=pycon file=Unbenannt.txt]except (AttributeError, cymysql.OperationalError):[/code]

mfg
Tom
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tom69: Du rufst Deine Funktionen mit fehlerhaften Daten auf, schaust, was passiert und überlegst Dir dann, was eine sinnvolle Fehlerbehandlung sein könnte.
Tom69
User
Beiträge: 4
Registriert: Freitag 27. Januar 2017, 09:54

Das Problem ist nicht den Fehler abzufangen, sondern welche Attribute ich hinter except angeben muss, welche stehen mir zur Verfügung!
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Deswegen sollst du ja Fehler von dir aus erzeugen mit fehlerhaften Daten!
Es bringt dir wenig, wenn du alle Exceptions behandelst die eventuell nie auftauchen.

Code: Alles auswählen

>>> import inspect
>>> [name for name, value in vars(sqlite3).items()
...      if inspect.isclass(value) and issubclass(value, Exception)]
['Warning', 'InternalError', 'ProgrammingError', 'NotSupportedError', 'DataError', 'IntegrityError', 'Error', 'InterfaceError', 'DatabaseError', 'OperationalError']
>>>

Tom69
User
Beiträge: 4
Registriert: Freitag 27. Januar 2017, 09:54

Bin leider noch nicht so lange mit python unterwegs, trotzdem vielen Dank für die Antwort.

Code: Alles auswählen

...      if inspect.isclass(value) and issubclass(value, Exception)]
['Warning', 'InternalError', 'ProgrammingError', 'NotSupportedError', 'DataError', 'IntegrityError', 'Error', 'InterfaceError', 'DatabaseError', 'OperationalError']
Verstehe ich das richtig mit

Code: Alles auswählen

except (AttributeError, sqlite3.DatabaseError):
kann ich den Fehler "DatabaseError" abfangen?

Wenn ich den Befehl

Code: Alles auswählen

dbCursor.cursor = dbConn.conn.cursor()
bekomme ich die Fehlermeldung

Code: Alles auswählen

AttributeError: 'NoneType' object has no attribute 'cursor'
Wie muss jetzt mein except-Befehl mit Attributen lauten um genau diesen Fehler abzufangen.

Vielen Dank nochmal's für die Hilfe!
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tom69. der letzte Fehler darf eigentlich gar nicht auftreten, weil Du dann schon vorher etwas falsch gemacht hast. Und an dieser späten Stelle ist er gar nicht sinnvoll behandelbar.
Tom69
User
Beiträge: 4
Registriert: Freitag 27. Januar 2017, 09:54

Sorry für die späte Antwort.
Ja, der Fehler sollte so nicht auftreten

Code: Alles auswählen

try:
   dbCursor.cursor = dbConn.conn.cursor()
   dbCursor.cursor.execute(sql)
except:
   connect()                        # Hier wird die Datenbank in einer Funktion geöffnet
   dbCursor.cursor = dbConn.conn.cursor()
   dbCursor.cursor.execute(sql)
Ziel ist es, in einer Funktion eine Datenbankabfrage durchzuführen, falls die Datenbank noch nicht geöffnet ist, wird sie geöffnet ( connect() ).
Hier bei diesem Beispiel, geht es aber bei jeder Fehlermeldung mit except weiter, egal ob die Datenbank noch nicht geöffnet ist oder ein Fehler bei der .execute-Anweisung auftritt.
Hier möchte ich dann mit except unterscheiden wer den Fehler erzeugt.

Vielen Dank!
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tom69: Du willst den Fehler an der falschen Stelle behandeln. Es ist Aufgabe des dbConn-Objekts, Dir einen gültigen Cursor zu liefern und nicht die jeder einzelnen Funktion, die einen Cursor will, das zu tun. Zudem gibt es den Fall, das eine Datenbank noch nicht geöffnet ist, bei SQLite gar nicht, denn mit dem Erzeugen eines Connection-Objekts ist die Datenbank automatisch geöffnet.

Der gezeigte Code sieht sehr merkwürdig aus. Es gibt ein dbConn (Datenbank-Connection?) Objekt, das aber wieder ein Attribut conn hat. Man würde ja erwarten, dass dbConn direkt einen Cursor liefern kann.
Dieser Cursor wird einem Objekt dbCursor als Attribut zugewiesen. Was ist denn das für eine Klasse? Cursor sind kurzlebig, die in einem Attribut zu speichern, wurde dem wiedersprechen. Du rufst direkt connect ohne Argumente auf. Wie soll denn diese Funktion auf magische Weise etwas an einem dbConn-Objekt ändern können?
Du wiederholst Anweisungen im try- und im except-Block, das ist ein deutliches Zeichen, dass Du eigentlich einen Fehler weiter vorne Abfangen willst.

Dein Code-Schnipsel sollte so aussehen:

Code: Alles auswählen

cursor = dbConn.cursor()
cursor.execute(sql)
Antworten