[PyQt4] sqlite und ? als Platzhalter

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Hallo

Gemäß sqlite3 Doku versuche ich folgendes:

Code: Alles auswählen

        suche = self.ui.lineSuche.text()
        query.exec_("SELECT id,name,vorname,strasse,plz,ort FROM personen WHERE name LIKE ?", ('%'+suche+'%'))
Dies erzeugt folgende Fehler:

Code: Alles auswählen

    query.exec_("SELECT id,name,vorname,strasse,plz,ort FROM personen WHERE name LIKE ?", ('%'+suche+'%'))
TypeError: arguments did not match any overloaded call:
  QSqlQuery.exec_(QString): too many arguments
  QSqlQuery.exec_(): too many arguments
Wenn ich die Abfrage ohne den Platzhalter mache bzw die in der Doku "verbotene" Schreibweise mache, dann geht es:

Code: Alles auswählen

query.exec_("SELECT id,name,vorname,strasse,plz,ort FROM personen WHERE name LIKE '%%%s%%'" % suche)
Ich hab gestern schon mehrere Stunden im www nach einer Lösung gesucht, leider ohne Erfolg. Letzte Hoffnung python-forum.de :wink:
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

@lackschuh: gemäß Doku müssen die Argumente eine Liste sein, Du übergibst aber nur einen String, dessen einzelne Zeichen dann als Listenelemente aufgefasst werden.

Code: Alles auswählen

query.exec_("SELECT id,name,vorname,strasse,plz,ort FROM personen WHERE name LIKE ?", ('%'+suche+'%', ))
Benutzeravatar
snafu
User
Beiträge: 6867
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ergänzend: Einelementrige Tupel müssen immer mit einem Komma abgeschlossen werden. Ansonsten werden sie als stinknormaler String in Klammern aufgefasst, wobei die Klammern ignoriert werden. Eine Funktion, die ein Iterable erwartet, durchläuft dann ungewollterweise die Elemente des Strings (also die einzelnen Zeichen).
Zuletzt geändert von snafu am Mittwoch 24. Juli 2013, 08:14, insgesamt 1-mal geändert.
BlackJack

Leute ihr seid beide in der falschen Doku. ;-) Wenn man wissen will wie `QSqlQuery` funktioniert und wie dort mit Platzhaltern verfahren wird, muss man in der Qt-Dokumentation nachlesen und nicht in der SQLite-Doku.

Edit: Ungetestet:

Code: Alles auswählen

        query.prepare(
            'SELECT id, name, vorname, strasse, plz, ort'
            ' FROM personen WHERE name LIKE ?'
        )
        query.addBindValue(u'%{0}%'.format(suche))
        query.exec_()
Benutzeravatar
snafu
User
Beiträge: 6867
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich hab nichtmal in irgendeine Doku geguckt, sondern einfach drauflos geschrieben, zumal ich davon ausging, dass die Antwort von Sirius3 grundsätzlich korrekt ist. :)
BlackJack

@snafu: Ich habe Dich auch gar nicht mit „beide” (mit)gemeint, Du bist ja der Dritte gewesen. :-) (Deinen Beitrag hatte ich zu dem Zeitpunkt noch nicht gesehen.)
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Ich habs auch schon mittels query.boundValue(suche) versucht, jedoch ohne Erfolg. Bzw. kommt dann folgende Meldung:

Code: Alles auswählen

    self.ui.lineID.setText(str(id))
UnboundLocalError: local variable 'id' referenced before assignment
Sonst poste ich mal die komplette Abfrage

EDIT I:
Ich probiere mal die von blackjack gepostete Variante

EDIT II:
Die BlackJack Variante geht.

Code: Alles auswählen

    def onSuche(self):
        suche = self.ui.lineSuche.text()
        query.prepare("SELECT id,name,vorname,strasse,plz,ort FROM personen WHERE name LIKE ?")
        #query.boundValue(suche) 
        query.addBindValue(u'%{0}%'.format(suche))
        query.exec_()
        while query.next():
            id = query.value(0).toInt()[0]
            name = unicode(query.value(1).toString())
            vorname = unicode(query.value(2).toString())
            strasse = unicode(query.value(3).toString())
            plz = query.value(4).toInt()[0]
            ort = unicode(query.value(5).toString())
#         
            print id, name, vorname, strasse, plz, ort
Antworten