Python重启项目数据库“被清空”的原因:sqlite3 commit 与配置文件排查指南

发布时间:2026/9/29 8:39:28

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 。
延伸阅读

更多相关文章

2026/9/29 8:39:28

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

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

2026/9/29 8:34:27

【Codex教育管理系统】接入音频转录服务维护转写参数与音频文件入口

音频转录服务在教育管理系统中的价值,在于围绕 音频转录服务 的核心字段、接口动作和页面状态维护业务数据。模块需要和现有接口、权限、页面状态保持一致,不能只写成普通后台表格。 本文基于 系统功能/三方服务_音频转录服务 对应源码,把业务目标拆成模型字段、接口规则、页…

2026/9/29 9:44:33

SpringBoot+uni-app驾考系统全链路源码解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/29 9:44:33

Servlet 在 JSP 里到底干什么

JSP 负责显示页面(给人看),Servlet 负责干活(后台处理) 核心作用(4 件事) 接收浏览器发来的请求、获取参数(表单提交、url 传参)做业务处理:判断逻辑、调用…

2026/9/29 9:44:33

STM32开发参考方案怎么找?国内资源平台与高频例程拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/29 9:44:33

反射电压详解:反激变压器设计中的核心权衡与实例计算

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/29 9:44:33

Allegro中DXF导入与元件精确放置全流程详解

做PCB设计的兄弟应该都有体会,结构工程师甩过来一个DXF,让你照着画板框、放定位孔、卡元件位置,结果你导入Allegro之后,尺寸对不上、图层乱成一锅粥、元件放半天也落不到该在的地方。今天就把这整套流程梳理一遍,从DXF…

2026/9/29 9:39:32

第一次作业全流程拆解:从题目分析到代码提交的避坑指南

“3.2第一次作业”这个标题,很多刚入门的同学一看会觉得稀松平常:不就是一个作业嘛。但根据我这几年带课、改作业的实际经验,真正决定一门课后续学习节奏的,恰恰就是这份看起来最简单的“第一次作业”。它检验的不是你有多聪明&am…

2026/9/28 3:03:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 7:00:49

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 0:04:04

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

2026/9/29 0:04:04

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

2026/9/29 3:53:39

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/26 19:58:38

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/29 6:36:14

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑