Python数据库编程入门:sqlite3 基础、增删改查与参数化查询
前面的几篇文章里,我们已经学会了处理文件、调用网络接口,也接触了常见第三方库。
但真实系统中的数据,很多时候并不是保存在:
- 普通文本文件;
- CSV 表格;
- JSON 文件。
而是保存在数据库里。
所以当你继续往工程方向走时,一个几乎绕不过去的问题就是:
Python 程序如何和数据库交互?
本文不会一开始就把内容拉到复杂的 MySQL、PostgreSQL 或 ORM 框架,而是先从 Python 标准库自带的 sqlite3 开始。
原因很简单:
- 它零安装、开箱即用;
- 足够覆盖数据库编程的核心思路;
- 特别适合初学者理解 SQL 和 Python 之间的协作方式。
本文会围绕下面几个主题展开:
- 什么是 SQLite;
- 如何连接数据库;
- 如何建表;
- 如何做增删改查;
- 为什么要使用参数化查询;
- 如何处理事务和异常。
理解这一章之后,你就能写出基本的数据存储程序,也能为后续学习 MySQL、ORM 和 Web 开发打下很好的基础。
一、为什么要学数据库编程?
文件当然可以保存数据,但它有局限:
- 查找和筛选不方便;
- 多条结构化记录不好管理;
- 更新某一部分数据比较麻烦;
- 并不适合复杂查询。
而数据库更擅长解决这些问题:
- 存储结构化数据;
- 支持条件查询;
- 支持排序、聚合、统计;
- 更适合长期持久化。
例如下面这些场景:
- 用户信息;
- 订单数据;
- 学生成绩;
- 日志记录;
- 配置和业务状态。
这些都很适合放在数据库中。
二、为什么先学 sqlite3?
SQLite 是一个轻量级数据库,它和很多传统数据库最大的区别之一是:
它通常不需要单独安装服务进程,一个数据库往往就是一个本地文件。
这非常适合初学阶段。
Python 标准库自带 sqlite3 模块,所以你几乎可以直接开始写。
2.1 适合初学者的原因
- 不需要额外部署数据库服务;
- 代码可以直接跑起来;
- 足够学习 SQL 和数据库交互的基础逻辑;
- 非常适合本地工具、小项目、原型验证。
2.2 先理解几个基础术语
- 数据库(database):存数据的整体容器;
- 表(table):数据库中的数据表;
- 行(row):一条记录;
- 列(column):字段;
- SQL:用来操作关系型数据库的语言。
三、连接数据库与创建表
3.1 连接数据库
1 | import sqlite3 |
这里:
- 如果
students.db不存在,通常会自动创建; conn表示数据库连接对象。
3.2 创建游标对象
在执行 SQL 语句之前,通常需要先创建游标:
1 | import sqlite3 |
可以先简单理解为:
游标是你和数据库“发命令、拿结果”的接口之一。
3.3 创建一张表
1 | import sqlite3 |
这里做了几件事:
- 建立连接;
- 创建游标;
- 执行建表 SQL;
commit()提交更改;- 关闭连接。
3.4 为什么 commit() 很重要?
数据库中的修改操作通常不是“写了就立刻永久生效”,而是先处于当前事务中。
只有提交后,修改才真正保存下来。
所以对初学者来说,一个很重要的习惯是:
- 查询不一定需要
commit(); - 插入、更新、删除通常记得
commit()。
四、插入数据:CREATE 之后就是 INSERT
4.1 插入一条记录
1 | import sqlite3 |
这里最值得注意的是:
1 | VALUES (?, ?, ?) |
这是参数化查询写法,后面还会重点讲。
4.2 插入多条记录
1 | import sqlite3 |
如果是批量插入,executemany() 通常更方便。
五、查询数据:SELECT 是最常见的操作之一
5.1 查询全部记录
1 | import sqlite3 |
这里:
fetchall()会取出所有结果;- 每一条记录通常是一个元组。
5.2 查询一条记录
1 | cursor.execute('SELECT name, score FROM students WHERE id = ?', (1,)) |
注意这里 (1,) 末尾有个逗号,因为它是单元素元组。
5.3 带条件查询
1 | cursor.execute('SELECT name, score FROM students WHERE score >= ?', (90,)) |
5.4 排序查询
1 | cursor.execute('SELECT name, score FROM students ORDER BY score DESC') |
5.5 限制返回条数
1 | cursor.execute('SELECT name, score FROM students ORDER BY score DESC LIMIT 3') |
这些已经能覆盖很多基础查询场景。
六、更新与删除:改数据和删数据
6.1 更新数据
1 | import sqlite3 |
6.2 删除数据
1 | import sqlite3 |
6.3 删除要特别小心
尤其是:
1 | DELETE FROM students |
如果不加 WHERE,通常会删除整张表的所有记录。
所以写删除语句时要非常谨慎。
七、参数化查询:为什么它这么重要?
这是数据库编程里非常关键的一部分。
很多初学者可能会下意识写出这种代码:
1 | name = 'Alice' |
这看起来好像能用,但它有明显问题:
- 容易出错;
- 可读性不稳定;
- 最重要的是:可能带来 SQL 注入风险。
更好的写法是参数化查询:
1 | cursor.execute('SELECT * FROM students WHERE name = ?', ('Alice',)) |
7.1 参数化查询的好处
- 更安全:避免拼接 SQL 带来的风险;
- 更清晰:SQL 结构和数据分离;
- 更容易维护:变量不用自己处理引号转义。
7.2 一个错误示例和正确示例对比
错误写法:
1 | name = "Alice' OR 1=1 --" |
正确写法:
1 | name = "Alice' OR 1=1 --" |
初学阶段请尽量形成一个硬习惯:
只要 SQL 里有外部变量,就优先参数化,不自己拼接。
八、事务、提交与回滚
数据库修改通常涉及事务。
你可以把事务简单理解为:
一组数据库操作,要么一起成功,要么一起失败。
8.1 正常提交
1 | conn.commit() |
8.2 出错回滚
1 | import sqlite3 |
这说明一个很重要的思路:
- 多个相关修改最好放在同一个事务里;
- 一旦失败,可以统一回滚。
九、让查询结果更好用:row_factory
默认情况下,查询结果是元组,例如:
1 | (1, 'Alice', 20, 95.5) |
有时你会希望像字典一样按列名访问。
1 | import sqlite3 |
这在结果字段较多时非常实用。
十、一个综合示例:学生成绩管理的基本流程
下面写一个稍微完整一点的示例,把建表、插入、查询串起来。
1 | import sqlite3 |
这个例子体现了数据库编程的基础闭环:
- 建表;
- 存数据;
- 查数据;
- 条件过滤;
- 排序输出。
十一、学习数据库编程时的常见误区
11.1 不要把 SQL 和 Python 逻辑混在一起乱拼
最好让:
- SQL 负责数据查询和数据变更;
- Python 负责业务流程和结果处理。
11.2 不要忘记关闭连接
哪怕是小程序,也建议养成好习惯:
- 用完连接及时关闭;
- 或者至少在
finally中关闭。
11.3 不要忽视参数化查询
这是数据库安全和可维护性的基础之一。
11.4 不要一开始就急着跳 ORM
ORM 很方便,但如果你完全不懂:
- 表是什么;
- SQL 在做什么;
- 事务和查询怎么工作;
那么后面遇到 ORM 问题会很难排查。
所以先学 sqlite3 和基础 SQL,是非常值得的。
十二、学习建议:这一章优先掌握什么?
12.1 先掌握 CRUD
也就是:
CREATEINSERTSELECTUPDATEDELETE
这是数据库交互最核心的 5 类操作。
12.2 先把参数化查询养成习惯
这件事越早形成越好。
12.3 先把事务和 commit() 理解清楚
不然后面很容易出现“为什么我明明执行了 SQL,数据却没保存”的困惑。
12.4 后续再扩展到 MySQL / PostgreSQL / ORM
当你把这篇吃透后,再学:
- MySQL 驱动;
- SQLAlchemy;
- Django ORM;
- FastAPI + 数据库;
都会顺畅很多。
十三、总结
这一篇我们系统梳理了 Python 中“数据库编程入门”的核心内容:
- 为什么需要数据库:理解数据库比普通文件更适合结构化数据管理;
sqlite3基础:学会连接数据库、创建游标和建表;- 插入数据:掌握单条插入和批量插入;
- 查询数据:掌握条件查询、排序和限制条数;
- 更新与删除:理解修改数据和删除数据的基本方式;
- 参数化查询:理解安全性和可维护性的重要性;
- 事务处理:掌握
commit()和rollback()的意义; - 结果处理优化:学会使用
sqlite3.Row提升可读性。
如果说前面的几篇在处理文件和网络数据,那么这一篇更像是在回答:
当数据需要长期保存、结构化管理,并支持条件查询时,Python 应该如何优雅地和数据库协作?
掌握这一篇之后,你就已经具备了最基础的数据库编程能力。
继续往后写时,比较自然的衔接方向通常有两个:
- Python并发编程与异步入门:进一步处理 I/O 任务和高并发请求;
- Python Web 开发入门:把数据库、网络请求和服务端结合起来。