python mysql db class error

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
skymuss

---------------------
Zuletzt geändert von skymuss am Samstag 12. Juni 2010, 10:55, insgesamt 1-mal geändert.
BlackJack

@skymuss: Die Fehlermedlung ist doch recht eindeutig: `long`-Objekte haben keine `fetchall()`-Methode. `execute()` auf dem `Cursor`-Objekt liefert eine Zahl zurück. Was die bedeutet, kann man in der Dokumentation zur DB-API 2.0 nachlesen.

Die Klasse heisst schon `db`, dann ist es nicht nötig allen Attributnamen auch nochmal diesen Präfix zu verpassen. Das betrifft Datenattribute und Methodennamen. Ausserdem sollten Klassennamen in `CamelCase` geschrieben werden, damit man erkennt, dass es sich um eine Klasse handelt. Einige Namen sind sehr nichtssagend; `conc`, `tab`, `tabc`, `inc`?

Anmerkungen zum Quelltext: Argumente auf Typen testen ist unpythonisch. Wenn die nicht passen, wird `connect()` schon eine entsprechende Ausnahme auslösen. Womit wir beim nächsten Thema wären: Diese komischen `True/`False`-Rückgabewerte. Zur Fehlerbehandlung verwendet man Ausnahmen und nicht jede Methode muss zwingend explizit einen Rückgabewert haben. Besonders blöd sind Funktionen, wie `db_sql()`, die verschiedene Typen zurückgeben können. Da *muss* man immer auf `False` testen, bevor man über das Ergebnis iterieren kann, weil `bool`-Exemplare nicht "iterable" sind.

Bei `db_insert_make()` wird's dann exotisch. `cgi.escape()` ist nicht geeignet jede Zeichenkette für SQL zu "escapen". Du ersetzt die Attribute `dbinrow` und `dbinval` durch eine "escapete" Verseion der ersten *drei Zeichen* von sich selbst!? Wenn man die Methode mehrfach aufruft, wird das *wiederholt* auf den schon "escapeten" Daten aufgerufen! Als Tabellenname wird ein Wahrheitswert verwendet. In der Methode wird noch einmal ein Exemplar der Klasse `db` erzeugt, nur um dessen `db_sql()`-Methode auf zu rufen. Das kann natürlich nicht klappen, weil dieses Exemplar gar keine Verbindung zur Datenbank aufgebaut hat.

Das Escapen von Werten sollte man dem Datenbank-Modul überlassen, siehe das zweite Argument von `Cursor.execute()`. Und Tabellennamen sollten gar nicht erst "escapet" werden müssen.
skymuss

---------------------
Zuletzt geändert von skymuss am Samstag 12. Juni 2010, 10:56, insgesamt 1-mal geändert.
BlackJack

Du musst halt die `execute()`-Methode auf dem richtigen Objekt aufrufen.

Unpythonisch: Das macht man so nicht in Python. Ist keine idiomatische Lösung. Weder das Testen auf die "richtigen" Typen, noch `True`/`False` als Rückgabe überall, ob die Funktion funktioniert hat, oder nicht.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

[wiki]Parametrisierte SQL-Queries[/wiki]

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
skymuss

---------------------
Zuletzt geändert von skymuss am Samstag 12. Juni 2010, 10:56, insgesamt 1-mal geändert.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Da fehlt ein Komma ;)

Code: Alles auswählen

('2') != ('2',)
Das erste ist ein String, das zweite ist ein Tupel und das brauchst du... (Wobei es auch eine Liste sein kann)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten