Python 标准库 sqlite3 入门:给小工具加一个零配置的本地数据库
一、场景:JSON 文件撑不住的时候
写 Python 小工具,数据存储往往要经历一条演进路线:一开始存在变量里,后来存 JSON 文件,再往后要按条件查、要并发写、要去重,JSON 就越来越吃力——每次读写都全量加载、过滤逻辑全部手写、多进程一起写还会互相覆盖。这时候不必急着上 MySQL,Python 标准库自带的 sqlite3 就够用:一个文件就是一个数据库,零安装、零配置、零服务,还能随脚本一起分发。
SQLite 是单文件嵌入式数据库,手机、浏览器内部都在用它。Python 3 内置 sqlite3 模块,import 即用,连 pip install 都省了。
二、五分钟跑通增删改查
import sqlite3
# 连接数据库(文件不存在会自动创建)
conn = sqlite3.connect("todo.db")
cur = conn.cursor()
# 建表
cur.execute("""
CREATE TABLE IF NOT EXISTS task (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
done INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now', 'localtime'))
)
""")
# 插入
cur.execute("INSERT INTO task (title) VALUES (?)", ("周报整理",))
conn.commit()
# 查询
for row in cur.execute("SELECT id, title, done, created_at FROM task WHERE done = 0"):
print(row)
# 更新与清理
cur.execute("UPDATE task SET done = 1 WHERE id = ?", (1,))
cur.execute("DELETE FROM task WHERE created_at < datetime('now', 'localtime', '-30 day')")
conn.commit()
conn.close()
两个细节值得注意:created_at 用 datetime('now','localtime'),是因为 SQLite 默认时间是 UTC;写操作后面都要跟 commit(),SQLite 默认开事务,忘了提交,进程一退出数据就没了。
三、新手最容易踩的三个坑
1. 拼接 SQL 引发注入。 永远不要用 f-string 或 % 拼 SQL:一旦传入的字符串里带引号,轻则报错,重则被注入。正确姿势是参数化占位符:
cur.execute("SELECT * FROM task WHERE title = ?", (kw,))
2. 逐条插入太慢。 批量写入用 executemany,比循环 execute 快一个数量级:
cur.executemany("INSERT INTO task (title) VALUES (?)", [("任务A",), ("任务B",)])
3. 连接没关闭。 推荐用 with 上下文管理事务,代码更稳:
with sqlite3.connect("todo.db") as conn:
conn.execute("INSERT INTO task (title) VALUES (?)", ("对账",))
conn.commit()
注意 with 块结束提交的是事务,连接对象本身仍需 close;不过一次性脚本跑完进程退出,影响也不大。
四、顺手导出 Excel 给业务同事
sqlite3 与 pandas 能无缝配合(pd.read_sql / df.to_sql),后台存 SQLite、前台导 Excel,比直接读写 xlsx 稳得多:
import pandas as pd
df = pd.read_sql("SELECT * FROM task", sqlite3.connect("todo.db"))
df.to_excel("tasks.xlsx", index=False)
五、什么时候该换数据库
SQLite 适合单机、单写多读、数据量几百 MB 以内的场景。当出现多进程高频并发写、多台机器共享数据、单表千万行以上时,再迁移 MySQL / PostgreSQL 也不迟——SQL 语句基本原样可用,迁移成本主要在部署运维,不在代码。
- 点赞
- 收藏
- 关注作者
评论(0)