Django中SQLite数据库执行Python脚本INSERT后锁定问题排查
解决Django SQLite脚本执行后数据库锁定问题
1. 彻底检查脚本的连接与事务释放逻辑
- 如果脚本用原生sqlite3库:必须确保连接在所有操作(包括异常场景)后关闭,用
finally块兜底,避免异常导致关闭逻辑未执行:import sqlite3 conn = None try: conn = sqlite3.connect('your_db.db') # 执行写入操作 conn.commit() except Exception as e: if conn: conn.rollback() raise e finally: if conn: conn.close() # 必须执行这一步释放连接 - 如果脚本用Django ORM:执行完所有写入操作后,手动关闭Django的数据库连接,避免连接池残留未释放的连接:
from django.db import connection, connections # 执行ORM写入操作 # 关闭当前默认连接 connection.close() # 或者遍历关闭所有数据库连接 for conn in connections.all(): conn.close() - 远程环境下,检查是否有脚本进程残留:用系统工具(Linux:
ps aux | grep python;Windows:任务管理器)杀掉所有相关Python进程,再测试网站操作。
2. 处理SQLite的事务与锁残留
- SQLite的独占锁会在未提交/回滚的事务结束后才释放,脚本中如果显式开启了事务(比如
BEGIN语句),必须确保执行COMMIT或ROLLBACK,哪怕操作失败。 - 检查数据库目录下的临时文件:
.db-journal(回滚日志)或.db-wal(预写日志),如果脚本异常退出,这些文件可能残留导致锁无法释放。在确认无进程操作数据库时,手动删除这些文件。
3. 排查远程环境与本地的差异
- 远程用AnyDesk运行脚本时,可能存在会话残留导致进程未彻底退出:比如脚本在后台运行(如
nohup python script.py &),需要确认进程已正常终止。 - 检查数据库文件权限:确保Django运行用户和脚本运行用户对数据库文件有读写权限,避免因权限问题导致锁文件无法自动清理。
4. 调整Django的连接配置
- 检查
settings.py中的CONN_MAX_AGE:如果设置了非零值,Django会复用连接,可能和脚本的残留锁冲突。可以临时设置为0(每次请求后关闭连接)测试:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', 'CONN_MAX_AGE': 0, } } - 在网站修改操作前,手动重置Django数据库连接,确保使用全新连接:
from django.db import connections connections['default'].close()
5. 定位持有锁的进程
- Linux系统:用
lsof your_db.db查看哪个进程正在占用数据库文件,找到PID后用kill -9 [PID]强制终止。 - Windows系统:使用Sysinternals的
handle.exe工具,执行handle.exe your_db.db找到进程,在任务管理器中结束该进程。
内容的提问来源于stack exchange,提问作者KarinP
相关产品推荐
相关产品推荐

