如何从我的数据库表中删除整个行,基于使用python的变量

时间:2017-11-06 10:58:55

标签: python sqlite

我想从我的数据库表中删除整行,当我的变量' row_id'是0,1,2,3等等。例如:当row_id为1时,我的脚本应删除带有值的行:" 1" " 2017年11月6日" " d" " d" "好",何时是2删除行的值:" 2" " 2017年11月6日" " SS" " SS" "送去修理"

我的数据库表"卡"看起来像这样:

ID,   date,            card,      serial_card,  statuscard
"1"   "2017-11-06"     "D"        "D"           "Good"
"2"   "2017-11-06"     "SS"       "SS"          "Sent to repair"

我试过:

 def delete(self):
     # Delete from Listbox
     selection = lb.curselection()
     lb.delete(selection[0])
     row_id=int(selection[0])
     print(row_id)
     c.execute("DELETE FROM  cards WHERE ID = ?",(row_id,))

我的完整源代码:

 from tkinter import *
 import sqlite3
 import time
 import datetime

 conn = sqlite3.connect('cards.db')
 c = conn.cursor()

 class MainWindow():
      def __init__(self,master):

           self.master=master
           self.master.geometry("220x120")
           self.master.title('Cards!')
           self.button2=Button(self.master,text="Status ASRU Cards",fg='blue',command=self.gotoasru)
           self.button2.place(x=50, y=20)
           self.button4=Button(self.master,text="Exit",fg='red',command=self.exit)
           self.button4.place(x=90, y=60)

      def exit(self):
           self.master.destroy()

      def gotoasru(self):
           root2=Toplevel(self.master)
           myGUI2=status_asru(root2)

 class status_asru():
     def __init__(self,master):
         self.master=master
         self.master.geometry("760x310")
         self.master.title('ASRU cards')
         self.connection = sqlite3.connect('cards.db')
         self.cur = self.connection.cursor()
         self.insert()
         self.button5=Button(self.master,text="Exit",fg='red',command= self.exit)
         self.button5.place(x=340,y=270)
     def exit(self):
         self.master.destroy()

     def insert(self):
         self.cur.execute('CREATE TABLE IF NOT EXISTS cards(ID INT AUTO_INCREMENT, date TEXT,card TEXT,serial_card TEXT,statuscard TEXT)')
         global insert_data
         global exit1
         global lb
         global readfromdatabase

         tipcard=StringVar()
         serial_card=StringVar()
         statuscard=StringVar()
         label1=Label(self.master,text='Insert card type:',fg='black')
         label1.place(x=5,y=120)
         label2=Label(self.master,text='Insert card SN:',fg='black')
         label2.place(x=5,y=140)
         label3=Label(self.master,text='Insert card status:',fg='black')
         label3.place(x=5,y=160)
         label4=Label(self.master,text='Select a card to be deleted from the top list',fg='black')
         label4.place(x=440,y=160)
         a=Entry(self.master,textvariable=tipcard)
         a.place(x=100,y=120)
         b=Entry(self.master,textvariable=serial_card)
         b.place(x=100,y=140)

         var1 = IntVar()
         CB1=Checkbutton(self.master, text="Good", variable=var1)
         CB1.place(x=100,y=160)
         var2 = IntVar()
         CB2=Checkbutton(self.master, text="Defect", variable=var2)
         CB2.place(x=160,y=160)
         var3 = IntVar()
         CB3=Checkbutton(self.master, text="Sent to repair", variable=var3)
         CB3.place(x=230,y=160)

         def insert_data():
             timestamp = str(datetime.datetime.now().date())
             card=tipcard.get()
             SN=serial_card.get()
             if var1.get() == 1 and var2.get() == 0 and var3.get() == 0:
                status='Good'
                c.execute("INSERT INTO cards (date, card, serial_card, statuscard) VALUES (?, ?, ?, ?)",(timestamp, card, SN, status))
                conn.commit()
             elif var1.get() ==0  and var2.get() == 1 and var3.get() == 0:
                status='Defect'
                c.execute("INSERT INTO cards (date, card, serial_card, statuscard) VALUES (?, ?, ?, ?)",(timestamp, card, SN, status))
                conn.commit()
             elif var1.get() ==0  and var2.get() == 0 and var3.get() == 1:
                status='Sent to repair'
                c.execute("INSERT INTO cards (date, card, serial_card, statuscard) VALUES (?, ?, ?, ?)",(timestamp, card, SN, status))
                conn.commit()
             elif var1.get() == 1 and var2.get() == 1 and var3.get() == 1:
                label5=Label(self.master,text='select only 1 status',fg='red')
                label5.place(x=105,y=180)
                var1.set(0)
                var2.set(0)
                var3.set(0)
             elif var1.get() == 0 and var2.get() == 0 and var3.get() == 0:
                label6=Label(self.master,text='select 1 status',fg='red')
                label6.place(x=105,y=180)
                var1.set(0)
                var2.set(0)
                var3.set(0)
             elif var1.get() == 1 and var2.get() == 1 and var3.get() == 0:

                label7=Label(self.master,text='select only 1 status',fg='red')
                label7.place(x=105,y=180)
                var1.set(0)
                var2.set(0)
                var3.set(0)
             elif var1.get() == 0 and var2.get() == 1 and var3.get() == 1:
                label8=Label(self.master,text='select only 1 status',fg='red')
                label8.place(x=105,y=180)
                var1.set(0)
                var2.set(0)
                var3.set(0)
             elif var1.get() == 1 and var2.get() == 0 and var3.get() == 1:                       
                label9=Label(self.master,text='select only 1 status',fg='red')
                label9.place(x=105,y=180)
                var1.set(0)
                var2.set(0)
                var3.set(0)

         lb = Listbox(self.master, width=120, height=6)
         scrollbar = Scrollbar(self.master, orient="vertical",command=lb.yview)
         scrollbar.pack(side="right", fill="y")
         lb.place(x=5,y=5)
         def readfromdatabase():
                self.cur.execute("SELECT * FROM cards")
                return self.cur.fetchall()
         data = readfromdatabase()
         for index, dat in enumerate(data):     
              lb.insert("end",'Card Type: '+dat[2]+3*' '+'SN: '+dat[3]+3*' '+'Status: '+dat[4]+3*' '+'Last modification date: '+dat[1] )
              self.delete=Button(self.master,text="Delete Card",fg='blue',command = lambda: delete(lb))
              self.delete.place(x=520, y=190)

              def delete(self):
                # Delete from Listbox
                selection = lb.curselection()
                lb.delete(selection[0])
                row_id=selection[0]
                print(row_id)
                c.execute("DELETE FROM  cards WHERE ID = {}".format(row_id))
                conn.commit()

         self.button4=Button(self.master,text="Insert new card",fg='green',command=insert_data)
         self.button4.place(x=100,y=200)




 def main():
      root=Tk()
      GUI=MainWindow(root)
      root.mainloop()

 if __name__ == '__main__':
      main()

1 个答案:

答案 0 :(得分:1)

你还没有说明问题所在,但是,我猜你发现有时从数据库中删除了错误的行,或者没有删除任何行?

这是因为curselection()返回的值是对应于当前所选项目的列表框中从零开始的位置的整数元组。对于您的示例,ID为" 1"的项目在列表框中的位置0。如果您选择该项curselection()将返回值0,而不是您需要删除ID为" 1"来自您的数据库。

同样,如果列表框中有3个项目位置为0,1和2,并且您删除了位置1中的项目,则最后一个项目将被提升到位置1以填补空白,并且列表框位置和行ID将不再同步。

您不能依赖数据库行ID和列表框位置匹配,因此您只能使用列表框位置可靠地删除表中的行。您需要使用

访问存储在所选项目中的实际字符串
lb.get(lb.curselection())

然后从字符串中提取行ID(您不会显示存储在列表框中的字符串,因此我无法确切地告知如何执行此操作)。

或者,您可以维护第二个数据结构以将列表框位置映射到行ID,字典或列表可以正常工作。这是一个粗略的例子:

from tkinter import *

master = Tk()

lb = Listbox(master)
lb.pack()

def callback():
    if not lb.curselection():
        return

    selection = int(lb.curselection()[0])
    row_id = lb.row_ids[selection]

    c.execute("DELETE FROM cards WHERE ID = ?", (row_id,))

    lb.delete(selection)
    del lb.row_ids[selection]

Button(master, text="Delete", command=callback).pack()

lb.row_ids = [1, 2, 3, 44, 12, 20]
for item in lb.row_ids:
    lb.insert(END, item)

mainloop()

此代码使用包含row_ids的列表,并为方便起见将该列表绑定到列表框对象。 Python列表的索引也是从零开始的,因此当删除列表框项时,相应的项将从row_ids列表中删除。