You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter应用删除SQLite记录时触发database locked错误

问题:SQLite数据库锁定导致Tkinter应用删除功能失败

我开发了一款带登录/注册页面的Tkinter应用,注册功能能正常向SQLite数据库插入新用户。主页面包含数据表格和删除按钮,删除功能代码如下:

def delete(self):
    with sqlite3.connect(env['DB']) as conn:
        selected = self.AuthTable.Table.item(self.AuthTable.Table.selection()[0])
        curr = conn.cursor()
        curr.execute("DELETE FROM 'Authentifiants' WHERE authId=?", (selected['tags'][0],))
        conn.commit()
            
    self.AuthTable.search()

执行删除时触发错误,报错信息如下:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1921, in __call__    
    return self.func(*args)
  File "F:\Acces Rapide\Desktop\Tech\d3v\WorkSpace\Projects\SecurityTemp\.venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 527, in _clicked
    self._command()
  File "f:\Acces Rapide\Desktop\Tech\d3v\WorkSpace\Projects\SecurityTemp\src\app\authentifiants.py", line 90, in <lambda>
    command=lambda: self.delete(),
  File "f:\Acces Rapide\Desktop\Tech\d3v\WorkSpace\Projects\SecurityTemp\src\app\authentifiants.py", line 104, in delete
    conn.commit()
sqlite3.OperationalError: database is locked

我原本以为是未关闭连接导致的问题,改用with语句管理连接后错误依旧。


解决思路及方案

  • 排查未关闭的连接:检查项目中其他操作数据库的代码(比如AuthTable.search()方法),确保所有数据库连接都被正确关闭。建议统一使用单例连接模式,避免同时存在多个数据库连接实例。
  • 处理SQLite文件锁冲突:SQLite写操作会锁定整个数据库文件,若此时有读取操作(比如表格刷新)未完成,会阻塞写操作。可以:
    1. 确保self.AuthTable.search()在数据库连接完全关闭后执行,或者通过Tkinter的after()方法延迟执行:
      def delete(self):
          with sqlite3.connect(env['DB']) as conn:
              selected = self.AuthTable.Table.item(self.AuthTable.Table.selection()[0])
              curr = conn.cursor()
              curr.execute("DELETE FROM 'Authentifiants' WHERE authId=?", (selected['tags'][0],))
              conn.commit()
          # 延迟100ms执行搜索,确保连接已释放
          self.AuthTable.after(100, self.AuthTable.search)
      
    2. 若应用涉及多线程,可在连接时添加check_same_thread=False参数(需自行保证线程安全):
      with sqlite3.connect(env['DB'], check_same_thread=False) as conn:
          # 原有代码
      
  • 检查文件权限:确认数据库文件所在目录具备读写权限,避免因权限问题导致锁定异常。
  • 修复数据库文件:备份现有数据库后,使用SQLite官方工具检查并修复可能损坏的数据库文件。

内容的提问来源于stack exchange,提问作者0xHouss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:25:17