【问题标题】:My code deletes last item in list and not the item i want我的代码删除了列表中的最后一项,而不是我想要的项目
【发布时间】:2021-10-09 19:07:24
【问题描述】:

我想创建一个函数,用户可以从数据库中获取用户列表,并可以选择从数据库中删除其中的一个。它看起来像我想要的那样,我将所有项目排成一行,每个项目都有一个删除按钮,它们的名称是正确的。但是该功能似乎没有按我想要的方式工作。如果我单击任何删除按钮,最后一个用户将被删除。我是新手,所以我确定我犯了一个错误,但我不知道在哪里。

def delete():
    conn = sqlite3.connect("database.db")
    c = conn.cursor()
    c.execute("DELETE FROM databasetable WHERE oid = " + str(i[5]))
    conn.commit()
    conn.close()

conn = sqlite3.connect("database.db")
c = conn.cursor()
c.execute("SELECT *, oid FROM databasetable")
listfromdatabase = c.fetchall()
conn.commit()
conn.close()

for i in listfromdatabase:
    label = Label(frameskidlararenamn, text=i[0])
    label.pack()
    button = Button(frameskidlarareknapp, text="Delete " + str(i[0]), command=delete)
    button.pack()

有什么想法吗?

【问题讨论】:

  • "SELECT *, oid FROM databasetable" --> "SELECT * FROM databasetable"
  • 我不确定我是否理解。如果我写“SELECT * FROM databasetable”,它不会返回 oid,只返回我创建的输入。
  • * --> 表的所有字段
  • 你确定这就是它在 sqlite 中的工作方式吗?因为如果我写 * 不会返回 oid,但它会以我写的方式正确返回。我不认为那是问题所在。如果我将列表打印到终端,一切看起来都是正确的。
  • 我正在使用 sqlite3。

标签: python database sqlite tkinter


【解决方案1】:

循环结束时for i in listfromdatabase: i 是最后一项。 所以删除函数删除了最后一项。

【讨论】:

    【解决方案2】:

    检查这是否有效,使用 lambda 函数将参数传递给命令。
    lambda : delete(i[5]) 更改为lambda item=i[5]: delete(item)

    button1 = [None for _ in range(len(listfromdatabase))]
    for n,i in enumerate(listfromdatabase):
        label = Label(frameskidlararenamn, text=i[0])
        label.pack()
        button1[n] = Button(frameskidlarareknapp, text="Delete " + str(i[0]),command=lambda item=i[5]: delete(item))
        button1[n].pack()
    
    def delete(item):
        conn = sqlite3.connect("database.db")
        c = conn.cursor()
        c.execute("DELETE FROM databasetable WHERE oid = " + str(item))
        conn.commit()
        conn.close()
    

    为了确定,请检查两个名称相同但功能不同的按钮。喜欢

    def printnum(num):
        #print num on a label or something
    button = Button(frameskidlarareknapp, text="print num 1", command=lambda: printnum(1))
    button.pack()
    button = Button(frameskidlarareknapp, text="print num 2", command=lambda: printnum(2))
    button.pack()
    

    【讨论】:

    • 感谢您的帮助。我试过这个,当我尝试 Max Strandberg 写的内容时,我不再遇到问题。但原来的问题又回来了。当我按下任何删除按钮时,列表中的最后一项被删除。
    • 我看到我写的原始帖子有点不正确。它不仅是第一个有效的删除按钮。每个删除按钮都有效,但它们都删除了最后一项。
    • 我觉得这可能与按钮名称相同,可能需要不同的按钮名称有关。更新了 3 行
    • 是的,这听起来合乎逻辑。你知道我应该如何编写我的代码来根据数据库中有多少用户给他们单独的名字吗?
    • 抱歉没有看到你更新的代码,会试试的。
    【解决方案3】:

    您对 delete 的定义设置为针对 i 的第五个元素

    def delete():
        conn = sqlite3.connect("database.db")
        c = conn.cursor()
        c.execute("DELETE FROM databasetable WHERE oid = " + str(i[5]))
        conn.commit()
        conn.close()
    

    您应该改为通过更改定义传入要删除的 oid

    def delete(oid):
        conn = sqlite3.connect("database.db")
        c = conn.cursor()
        c.execute("DELETE FROM databasetable WHERE oid = " + str(oid))
        conn.commit()
        conn.close()
    

    【讨论】:

    • 当我尝试这个时,我得到了这个错误:sqlite3.OperationalError: near "E": syntax error
    • 您是否也更改了按钮的定义?它必须将正确的参数传递给命令,例如 command=delete(i[0]) 或存储 oid 的任何索引都可以解决问题
    • 不,我没有。我现在更改了它,这导致了一个新问题,我不知道为什么。现在所有用户都被删除,而我没有做任何事情。如果我添加新用户并再次打开窗口,则只有新用户存在。如果我关闭窗口并再次打开它,则没有用户在那里。当我在 for 循环之前将列表打印到终端时,列表为空。
    • 尝试制作命令 lambda,因此您将其定义为 command=lambda: delete(i[5])。它有可能会无意中在加载时触发
    • 在您发表评论后查看我对谁提出此建议的回答。我试过了,我摆脱了错误,但原来的问题又回来了。所有删除按钮都会删除最后一项。
    猜你喜欢
    • 2021-07-08
    • 2020-09-03
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 2017-03-15
    • 2020-09-12
    相关资源
    最近更新 更多