Seite 1 von 1

Probleme beim Löschen eines Datensatzes in Sqlite3

Verfasst: Donnerstag 6. August 2009, 15:57
von Spleen
Hey Leute,

habe da ein Fehler bei dem ich nicht weiterkomme und hoffe, dass mir jemand weiter helfen könnte.

In einer ListCtrl werden alle meine Datensätze angezeigt. Zum Löschen wird ein Datensatz angeklickt und der Löschen-Button gedrückt. Das funktioniert auch alles ohne Probleme - bis ich einen Datensatz mit einer zweistelligen ID löschen will.

Hier mal mein Code (es sind drei Module/Dateien - für die Applikation, für das Frame, für die Funktionen)

#App:

Code: Alles auswählen

class BoaApp(wx.App):
    def OnInit(self):
        self.main = FilmarchivFrame1.create(None)
        self.main.Show()
        self.SetTopWindow(self.main)
        return True

def main():
    application = BoaApp(0)
    application.MainLoop()

if __name__ == '__main__':
    main()
#Frame:

Code: Alles auswählen

class Frame1(wx.Frame):

    def _init_coll_menuFilm_Items(self, parent):
        parent.Append(help='Einen neuen Film hinzuf\xfcgen',
              id=wxID_FRAME1MENUFILMITEMS_HINZUFUEGEN, kind=wx.ITEM_NORMAL,
              text='Hinzuf\xfcgen')
        parent.Append(help='Den aktuellen Film l\xf6schen',
              id=wxID_FRAME1MENUFILMITEMS_LOESCHEN, kind=wx.ITEM_NORMAL,
              text='L\xf6schen')


    def _init_coll_menuBar1_Menus(self, parent):
        parent.Append(menu=self.menuFilm, title='Film')


    def _init_coll_listCtrl_Film_Tabelle_Columns(self, parent):
        parent.InsertColumn(col=0, format=wx.LIST_FORMAT_RIGHT, heading='ID',
              width=-1)
        parent.InsertColumn(col=1, format=wx.LIST_FORMAT_LEFT, heading='Kunde',
              width=-1)
        parent.InsertColumn(col=2, format=wx.LIST_FORMAT_LEFT, heading='Titel',
              width=-1)
        parent.InsertColumn(col=3, format=wx.LIST_FORMAT_LEFT,
              heading='Redakteur', width=-1)
        parent.InsertColumn(col=4, format=wx.LIST_FORMAT_LEFT,
              heading='Kategorie', width=-1)
        parent.InsertColumn(col=5, format=wx.LIST_FORMAT_LEFT, heading='Status',
              width=-1)
        parent.InsertColumn(col=6, format=wx.LIST_FORMAT_LEFT, heading='Medium',
              width=-1)
        parent.InsertColumn(col=7, format=wx.LIST_FORMAT_LEFT,
              heading='Sprache', width=-1)

        liste = FilmarchivFunktionen1.tabelle_anzeigen()
        for i in liste:
            parent.InsertStringItem(0, str(i[0]))
            parent.SetStringItem(0,1, i[1])
            parent.SetStringItem(0,2, i[2])
            parent.SetStringItem(0,3, i[3])
            parent.SetStringItem(0,4, i[4])
            parent.SetStringItem(0,5, i[5])
            parent.SetStringItem(0,6, i[6])
            parent.SetStringItem(0,7, i[7])


    def _init_utils(self):
        self.menuFilm = wx.Menu(title='')
        self.menuBar1 = wx.MenuBar()
        self._init_coll_menuFilm_Items(self.menuFilm)
        self._init_coll_menuBar1_Menus(self.menuBar1)


    def _init_ctrls(self, prnt):
        wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,
              pos=wx.Point(156, 34), size=wx.Size(1288, 1058),
              style=wx.DEFAULT_FRAME_STYLE, title='Filmarchiv')
        self._init_utils()
        self.SetClientSize(wx.Size(1280, 1024))
        self.SetMenuBar(self.menuBar1)

        self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,
              pos=wx.Point(0, 0), size=wx.Size(1280, 981),
              style=wx.TAB_TRAVERSAL)

        self.listCtrl_Film_Tabelle = wx.ListCtrl(id=wxID_FRAME1LISTCTRL_FILM_TABELLE,
              name='listCtrl_Film_Tabelle', parent=self.panel1, pos=wx.Point(5,
              30), size=wx.Size(1270, 698),
              style=wx.LC_SINGLE_SEL | wx.LC_REPORT)
        self.listCtrl_Film_Tabelle.SetLabel('')
        self.listCtrl_Film_Tabelle.Center(wx.HORIZONTAL)
        self.listCtrl_Film_Tabelle.SetHelpText('')
        self._init_coll_listCtrl_Film_Tabelle_Columns(self.listCtrl_Film_Tabelle)
        self.listCtrl_Film_Tabelle.Bind(wx.EVT_LIST_ITEM_SELECTED,
              self.OnListCtrl_Film_TabelleListItemSelected,
              id=wxID_FRAME1LISTCTRL_FILM_TABELLE)


    def __init__(self, parent):
        self._init_ctrls(parent)


    def OnMenuFilmItems1_loeschenMenu(self, event):
        zeile = self.listCtrl_Film_Tabelle.GetFocusedItem()
        id = self.listCtrl_Film_Tabelle.GetItemText(zeile)
        id = str(id)
        FilmarchivFunktionen1.loeschen(id)
#Funktionen:

Code: Alles auswählen

def tabelle_erstellen():
    connection = sqlite3.connect("T:/tmp/Max_Hanauer/Filmarchiv/EasyEclipse for Python/Filmarchiv/src/Datenbank/Filmarchiv_Datenbank.db")
    cursor = connection.cursor()
    cursor.execute("""CREATE TABLE Film (id TEXT, kunde TEXT, titel TEXT, redakteur TEXT, kategorie TEXT, status TEXT, medium TEXT, sprache TEXT )""")


def loeschen(id):
    connection = sqlite3.connect("T:/tmp/Max_Hanauer/Filmarchiv/EasyEclipse for Python/Filmarchiv/src/Datenbank/Filmarchiv_Datenbank.db")
    cursor = connection.cursor()
    sql = "DELETE FROM Film WHERE id = (?)"
    cursor.execute(sql, id)
    connection.commit()
Als Exception bekomme ich immer ein:
cursor.execute(sql, werte)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 2 supplied.

Obwohl die übergebene id ein string oder integer ist (beider ausprobiert).
Wie gasagt, ist die Zahl einstellig gibt es keine Probleme.

Danke schon mal im Voraus

Gruß,
Spleen

Verfasst: Donnerstag 6. August 2009, 16:03
von EyDu
Der zweite Parameter von execute muss ein Tupel sein:

Code: Alles auswählen

cursor.execute(sql, (id,))
Den Code hättest du ruhig noch etwas kürzen können. Der letzte Block und

Code: Alles auswählen

id = str(id)
FilmarchivFunktionen1.loeschen(id)
hätten locker gereicht.

Der zweite Google-Treffer mit "sqlite3.ProgrammingError: Incorrect number of bindings supplied." hätte dir schon geholfen ;-)

Verfasst: Donnerstag 6. August 2009, 16:10
von Spleen
Hey,

Habe es einfach so geschrieben:

Code: Alles auswählen

cursor.execute("DELETE FROM Film WHERE id = (%s)" %(id))
Jetzt funktionierts.

Danke

Verfasst: Donnerstag 6. August 2009, 16:18
von EyDu
Das willst du so aber nicht machen, da dir das unter Umständen sicherheitskritische Lücken bereitet (SQL-Injection). Besonders bei von Benutzern erzeugten Daten ist das sehr Problematisch. Vergesse daher deinen Ansatz sofort wieder und versuche immer execute zu benutzen. Das solltest du immer dann machen, wenn du mit Werten arbeitest, welche in die Anfrage eingetragen werden.

Verfasst: Donnerstag 6. August 2009, 16:39
von Spleen
Alles klar. Wurde jetzt in...

Code: Alles auswählen

def loeschen(id):
    connection = sqlite3.connect("T:/tmp/Max_Hanauer/Filmarchiv/EasyEclipse for Python/Filmarchiv/src/Datenbank/Filmarchiv_Datenbank.db")
    cursor = connection.cursor()
    sql = "DELETE FROM Film WHERE id = (?)"
    cursor.execute(sql, (id,))
    connection.commit()
...geändert.

Danke nochmals

Gruß,
Spleen