尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python重启项目数据库“被清空”的原因:sqlite3 commit 与配置文件排查指南
1. 重启后数据消失先别怀疑人生你写了个 Python 小工具用 sqlite3 存用户、存配置、存爬下来的数据。跑起来一切正常insert没报错select当场也能查到。结果关掉程序、第二天再跑select *返回空列表表还在数据没了。第一反应通常是数据库文件被谁删了是不是路径写错了还是 sqlite3 有 bug我试过在同一个坑里蹲了半个下午最后发现根因朴素得让人想笑insert 之后没有 commit。sqlite3 默认不会自动提交事务你的写入停留在连接自己的事务缓冲里程序一退出连接一关这些改动就被回滚了。表结构之所以还在是因为create table if not exists这类 DDL 在某些情况下会触发隐式提交或者你之前某次运行恰好提交过于是出现「表在、数据没」的诡异现象。这篇就围绕 Python sqlite3 项目重启后数据丢失这个场景从三条线索切入commit 缺失、连接关闭方式、数据库文件路径漂移。每条都给出可复制的代码骨架和验证动作让你能自己定位到底是哪一环出了问题。适合刚接触 sqlite3 的 Python 开发者也适合被「数据被清空」折磨过、想彻底搞明白事务边界的人。2. 三条线索commit、连接、路径2.1 commit 缺失最常见也最隐蔽sqlite3 的 Python 驱动遵循 DB-API 规范默认isolation_level是空字符串意味着它自动开启事务但不会自动提交。你执行insert、update、delete后改动只在当前连接的事务里可见其他连接看不到程序退出后直接丢弃。import sqlite3 conn sqlite3.connect(user.db) c conn.cursor() c.execute(create table if not exists users(userid text primary key, password text)) c.execute(insert into users values(?, ?), (u001, pwd001)) # 到这里没报错但数据没落盘 conn.close() # 事务回滚数据消失正确做法是显式conn.commit()或者把连接设成自动提交模式。注意c.execute(commit)这种写法虽然能跑但语义上应该用连接对象的commit()更清晰也更安全。2.2 连接关闭方式close 之前有没有 commit很多人以为conn.close()会自动保存其实不会。close()只是释放连接资源未提交的事务会被回滚。如果你用with语句管理连接也要注意with sqlite3.connect(...)在退出时只提交或回滚事务不关闭连接这点和文件对象的with行为不一样。# 错误示范with 里没 commit退出时行为依赖 isolation_level with sqlite3.connect(user.db) as conn: conn.execute(insert into users values(?, ?), (u002, pwd002)) # 这里其实会提交但很多人误以为 with 会关闭连接真正危险的是手动close()前忘了commit()或者异常路径下commit()没执行到。2.3 路径漂移你以为写的是同一个文件第三个高频原因是数据库文件路径不一致。开发时用相对路径user.db在 PyCharm 里运行工作目录是项目根数据库落在根目录换成命令行python src/main.py运行工作目录变成src/于是又新建了一个空的user.db。你查的是新文件当然没数据。import os print(os.getcwd()) # 每次运行前打印工作目录能快速发现路径漂移 print(os.path.abspath(user.db))配置文件里的路径如果写的是相对路径同样会随启动方式变化。下面会给出基于settings.json和config.toml的路径校验片段。3. TaoToken 前置把模型接进排查流程排查这类问题时我习惯让模型帮我快速生成对比代码和检查清单省去翻文档的时间。TaoToken 是一个模型调用入口兼容常见 API 格式适合把对话模型接进日常开发流程。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。你需要先拿到 API Key在控制台创建即可https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建后到 API Keys 页面复制https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各语言的调用示例。如果你只是想验证模型能不能正确解释 sqlite3 事务行为可以直接用模型对话页面https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。长期做编码和 Agent 任务的话Coding Plan 更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。Claude Code 相关接入参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。拿到 Key 后用环境变量管理别硬编码进代码export TAOTOKEN_API_KEY你的key4. 可复制配置连接骨架与路径校验4.1 sqlite3 连接与 commit 骨架下面这个骨架把连接、事务、异常回滚、关闭都包好了直接拿去改表名和 SQL 即可。import sqlite3 import logging from contextlib import contextmanager logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) DB_PATH user.db contextmanager def get_conn(db_pathDB_PATH): conn sqlite3.connect(db_path, timeout10) conn.row_factory sqlite3.Row try: yield conn conn.commit() logger.info(事务已提交) except Exception as e: conn.rollback() logger.error(事务回滚: %s, e) raise finally: conn.close() logger.info(连接已关闭) def init_db(): with get_conn() as conn: conn.execute( create table if not exists users( userid text primary key, password text not null ) ) def insert_user(userid, password): with get_conn() as conn: conn.execute(insert or replace into users values(?, ?), (userid, password)) logger.info(插入用户 %s, userid) def list_users(): with get_conn() as conn: rows conn.execute(select * from users).fetchall() return [dict(r) for r in rows] if __name__ __main__: init_db() insert_user(u001, pwd001) print(list_users())关键点yield之后先commit()再close()异常时rollback()。这样无论正常还是异常路径事务状态都是确定的。4.2 settings.json 路径校验如果你的项目用 JSON 配置加一段启动时校验能立刻发现路径漂移。import json import os def load_settings(pathsettings.json): with open(path, r, encodingutf-8) as f: cfg json.load(f) db_path cfg.get(db_path, user.db) abs_path os.path.abspath(db_path) cfg[db_path_abs] abs_path logger.info(数据库绝对路径: %s, abs_path) logger.info(文件是否存在: %s, os.path.exists(abs_path)) if os.path.exists(abs_path): logger.info(文件大小: %d 字节, os.path.getsize(abs_path)) return cfgsettings.json示例{ db_path: data/user.db, log_level: INFO }4.3 config.toml 路径校验用 TOML 的项目同理Python 3.11 自带tomllib。import tomllib import os def load_config(pathconfig.toml): with open(path, rb) as f: cfg tomllib.load(f) db_path cfg.get(database, {}).get(path, user.db) abs_path os.path.abspath(db_path) print(f数据库绝对路径: {abs_path}) print(f是否存在: {os.path.exists(abs_path)}) return cfgconfig.toml示例[database] path data/user.db timeout 10注意相对路径永远相对于当前工作目录不是脚本所在目录。要相对脚本定位用os.path.dirname(os.path.abspath(__file__))拼。5. 验证请求重启前后数据比对光看代码不够得用动作验证。下面这套流程能帮你确认数据到底有没有落盘。第一步运行插入脚本记录当前数据# before_restart.py from db import init_db, insert_user, list_users init_db() insert_user(u100, pwd100) print(插入后:, list_users())第二步另开一个进程模拟重启只读查询# after_restart.py from db import list_users print(重启后:, list_users())第三步用 sqlite3 命令行直接查文件绕开 Python 层sqlite3 user.db select * from users;如果 Python 查得到、命令行查不到说明你连的可能是另一个文件回到 4.2 打印绝对路径对比。如果两边都查不到基本就是 commit 没执行。第四步检查文件修改时间确认写入是否真的发生ls -l --time-stylefull-iso user.db插入前后时间戳没变说明数据没落盘。如果你想让模型帮你分析两次查询结果的差异可以把输出贴到模型对话里https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。需要程序化调用的话用 API 端点配合你的 Keyimport os import requests api_key os.environ[TAOTOKEN_API_KEY] resp requests.post( https://taotoken.net/api/chat/completions, headers{Authorization: fBearer {api_key}}, json{ model: gpt-4o-mini, messages: [ {role: user, content: sqlite3 insert 后没 commit程序退出数据会怎样} ] }, timeout30 ) print(resp.json()[choices][0][message][content])6. 本篇常见错排查6.1 报错database is locked多进程或多线程同时写同一个 sqlite 文件会锁。解决加timeout参数或改用 WAL 模式。conn sqlite3.connect(user.db, timeout10) conn.execute(pragma journal_modewal)6.2 表存在但数据为空回到第 2 节三条线索逐条查先打印os.path.abspath确认文件再用命令行select确认落盘最后检查代码里commit()是否在close()之前执行。6.3 with 语句没提交with sqlite3.connect(...)退出时会提交但如果你在with内部又手动close()了连接后续提交会失败。别在with里手动关连接。6.4 异常被吞导致没回滚用try/except包住 SQL 时如果except里只pass事务状态会悬空。要么rollback()要么让异常继续抛。6.5 路径含中文或空格sqlite3 对路径支持没问题但配置文件解析时注意编码。JSON 用encodingutf-8TOML 用二进制模式读。6.6 多线程共用连接sqlite3 连接默认不能跨线程。每个线程建自己的连接或用连接池。报错通常是SQLite objects created in a thread can only be used in that same thread。排障时如果拿不准事务边界把关键代码贴给模型让它帮你标出 commit 位置https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 拿 Key接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。7. 把 commit 写进肌肉记忆sqlite3 的数据丢失九成不是数据库坏了而是事务没提交、连接关早了、文件找错了。把第 4 节的get_conn骨架抄进你的项目每次写库都走这个上下文管理器commit 和 rollback 就不用你操心了。路径方面启动时打印一次绝对路径比事后 debug 省事得多。长期做 Python 编码和 Agent 任务的话Coding Plan 能帮你把模型调用固定下来https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。需要快速验证模型对 sqlite3 行为的解释用模型对话页面就行https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。控制台管理 Key 和用量https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。
RELATED

相关推荐

Java操作Redis:客户端选型、序列化与分布式锁实战指南

Java操作Redis:客户端选型、序列化与分布式锁实战指南

最近在折腾 Redis 相关的项目,发现不少同行在 Java 操作 Redis 客户端这块还在"能用就行"的阶段。Jedis、Lettuce、Redisson 到底怎么选?连接池参数调多少合适?序列化器的坑踩了也不知道怎么排查?这些都是实际开发里绕不…

📅 2026/9/29 8:39:37
将经验沉淀为工作流与可复用输出系统

将经验沉淀为工作流与可复用输出系统

这一年,我写博客的目标越来越清晰:不是“分享一个技巧”,而是把它变成一段能跑起来的链路,最后沉淀为别人也能照着复刻的方案。 所以会看到我写的内容跨度很大:AIGC 工具平台、Dify / n8n 自动化、Coze 内容生产、数字…

📅 2026/9/29 8:39:37
KeyarchOS上部署OpenClaw:数据中心AI运维管家实战

KeyarchOS上部署OpenClaw:数据中心AI运维管家实战

数据中心里最磨人的不是故障,而是那些“半夜响一次的假告警”和“每天重复八百遍的巡检”。以前在IDC做运维的时候,凌晨被电话叫起来处理一条误报是家常便饭。后来我逐渐形成一个判断:与其盯着监控大屏,不如训练一个AI管家来处理这…

📅 2026/9/29 8:39:37
MORE NEWS

更多资讯

📰

工控现货的核心竞争力:型号覆盖、版本准确与响应速度

1. 工控现货这门生意,远不止“有货就卖”这么简单干了十几年工业自动化这一行,我越来越觉得“工控现货”这四个字被严重低估了。外行看,不就是倒买倒卖PLC、变频器、伺服电机吗?但真正在这个圈子里摸爬滚打过的人都知道&#xff0…

📰

谢希仁计算机网络第8版电子资料:结构化复习系统构建指南

简介:本资源是面向计算机专业本科生及考研备考者的《计算机网络》期末复习精要电子版资料,严格依据谢希仁《计算机网络》第8版教材核心内容梳理,聚焦高频考点与易错难点,助力高效冲刺。资料以1个结构清晰的Word文档(.d…

📰

赣州外贸定制屏风生产厂行业现状与选择指南

赣州榫兴智能家具有限公司坐落于南康家具产业带,是深耕行业15年的木工世家源头工厂,专注木质工艺研发与精细化生产,核心主营艺术屏风定制、设计与精工制作,配套承接各类木配件、木质工艺品加工及家具打样业务,依托传统…

📰

2026亲测有效:比PanDownload更稳的百度网盘高速解析下载器分享

很多朋友在使用电脑下载资料的时候,总觉得明明家里办的宽带规格很高,但是实际下载的数字却始终上不去。眼看着几十兆的文件都要等待许久,确实会让人心里产生不少焦虑。 要想弄清楚其中的缘由,不妨多从我们自己手头的硬件和线缆配…

📰

集成成像传感器与像差校正:三维摄影从硬件源头突破

拿到这个标题,我第一反应是:三维摄影这个事,终于要往“传感器本身”这个根子上钻了。过去几年大家聊3D成像,基本都是算法在补天——深度估计网络、多视图几何、NeRF换着花样上,但采集端用的还是普通二维传感器&#xf…

📰

业之峰怡家装饰公司靠谱吗,值得信赖吗

滨州业之峰怡家装饰有限公司是扎根滨州本土,依托业之峰全国连锁体系,聚焦新房整装、老房全屋翻新、别墅大宅全案三大核心业务,主打靠谱落地、透明省心一站式家装服务的本土专业家装品牌。 核心实力拆解 正规合规的资质背书,稳定经…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬