news 2026/4/21 13:42:53

Python 连接 SQLite 数据库:从建表到增删改查的完整演示项目

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 连接 SQLite 数据库:从建表到增删改查的完整演示项目

Python 连接 SQLite 数据库:从建表到增删改查的完整演示项目

SQLite 是 Python 新手非常适合上手的数据库:它不需要单独安装数据库服务,数据直接保存在一个本地.db文件里。Python 标准库内置了sqlite3模块,所以只要安装了 Python,就可以直接操作 SQLite。

这篇文章用一个“小型学生信息管理”项目演示 Python 如何连接 SQLite 数据库,并完成建表、插入、查询、更新、删除等常见操作。

一、项目目标

我们要实现一个简单的学生表students,字段如下:

字段类型说明
idINTEGER主键,自增
nameTEXT学生姓名
ageINTEGER年龄
majorTEXT专业
scoreREAL分数

最终项目支持这些功能:

  1. 自动创建数据库和数据表
  2. 新增学生信息
  3. 查询全部学生
  4. 根据 ID 查询单个学生
  5. 修改学生分数
  6. 删除学生记录
  7. 关闭数据库连接

二、准备环境

确认本机已经安装 Python:

python--version

如果能看到类似下面的输出,就可以继续:

Python3.11.0

sqlite3是 Python 标准库,不需要额外安装。

三、项目结构

新建一个目录,例如:

sqlite_crud_demo/ ├── app.py └── student.db

其中:

  • app.py:我们编写的 Python 代码
  • student.db:运行程序后自动生成的 SQLite 数据库文件

四、完整代码

app.py中写入下面的代码:

importsqlite3frompathlibimportPath DB_PATH=Path(__file__).with_name("student.db")defget_connection():"""创建并返回数据库连接。"""conn=sqlite3.connect(DB_PATH)conn.row_factory=sqlite3.Rowreturnconndefcreate_table(conn):"""创建学生表。"""sql=""" CREATE TABLE IF NOT EXISTS students ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER NOT NULL, major TEXT NOT NULL, score REAL NOT NULL ); """conn.execute(sql)conn.commit()defadd_student(conn,name,age,major,score):"""新增学生。"""sql=""" INSERT INTO students (name, age, major, score) VALUES (?, ?, ?, ?); """cursor=conn.execute(sql,(name,age,major,score))conn.commit()returncursor.lastrowiddeflist_students(conn):"""查询全部学生。"""sql="SELECT id, name, age, major, score FROM students ORDER BY id;"returnconn.execute(sql).fetchall()defget_student_by_id(conn,student_id):"""根据 ID 查询学生。"""sql="SELECT id, name, age, major, score FROM students WHERE id = ?;"returnconn.execute(sql,(student_id,)).fetchone()defupdate_student_score(conn,student_id,new_score):"""修改学生分数。"""sql="UPDATE students SET score = ? WHERE id = ?;"cursor=conn.execute(sql,(new_score,student_id))conn.commit()returncursor.rowcountdefdelete_student(conn,student_id):"""删除学生。"""sql="DELETE FROM students WHERE id = ?;"cursor=conn.execute(sql,(student_id,))conn.commit()returncursor.rowcountdefprint_students(rows):"""格式化输出查询结果。"""ifnotrows:print("暂无学生数据")returnforrowinrows:print(f"id={row['id']}, "f"name={row['name']}, "f"age={row['age']}, "f"major={row['major']}, "f"score={row['score']}")defmain():withget_connection()asconn:create_table(conn)print("=== 新增学生 ===")alice_id=add_student(conn,"Alice",20,"Computer Science",92.5)bob_id=add_student(conn,"Bob",21,"Data Science",88.0)add_student(conn,"Cindy",19,"Software Engineering",95.0)print(f"Alice 的 ID 是:{alice_id}")print(f"Bob 的 ID 是:{bob_id}")print("\n=== 查询全部学生 ===")print_students(list_students(conn))print("\n=== 根据 ID 查询学生 ===")student=get_student_by_id(conn,alice_id)ifstudent:print(dict(student))print("\n=== 修改 Bob 的分数 ===")updated_count=update_student_score(conn,bob_id,90.5)print(f"更新记录数:{updated_count}")print("\n=== 修改后再次查询 ===")print_students(list_students(conn))print("\n=== 删除 Alice ===")deleted_count=delete_student(conn,alice_id)print(f"删除记录数:{deleted_count}")print("\n=== 删除后再次查询 ===")print_students(list_students(conn))if__name__=="__main__":main()

运行程序:

python app.py

第一次运行后,当前目录会自动生成student.db文件。

五、关键代码讲解

1. 连接 SQLite 数据库

conn=sqlite3.connect(DB_PATH)

如果student.db已经存在,Python 会直接连接它;如果文件不存在,SQLite 会自动创建。

这里还设置了:

conn.row_factory=sqlite3.Row

这样查询出来的每一行既可以像元组一样访问,也可以通过字段名访问:

row["name"]row["score"]

这对新手更直观。

2. 创建数据表

CREATETABLEIFNOTEXISTSstudents(idINTEGERPRIMARYKEYAUTOINCREMENT,nameTEXTNOTNULL,ageINTEGERNOTNULL,majorTEXTNOTNULL,scoreREALNOTNULL);

IF NOT EXISTS的作用是:如果表已经存在,就不会重复创建,也不会报错。

id INTEGER PRIMARY KEY AUTOINCREMENT表示id是主键,并且会自动递增。

3. 新增数据

sql=""" INSERT INTO students (name, age, major, score) VALUES (?, ?, ?, ?); """conn.execute(sql,(name,age,major,score))conn.commit()

注意这里没有把变量直接拼接到 SQL 字符串里,而是使用了?占位符。

推荐写法:

conn.execute(sql,(name,age,major,score))

不推荐写法:

sql=f"INSERT INTO students (name) VALUES ('{name}')"

原因是字符串拼接容易引发 SQL 注入问题,也容易因为引号、特殊字符导致 SQL 执行失败。

4. 查询数据

查询全部学生:

rows=conn.execute("SELECT * FROM students").fetchall()

查询单个学生:

row=conn.execute("SELECT * FROM students WHERE id = ?",(student_id,)).fetchone()

这里(student_id,)后面的逗号不能省略。它表示这是一个只包含一个元素的元组。

5. 修改数据

sql="UPDATE students SET score = ? WHERE id = ?;"cursor=conn.execute(sql,(new_score,student_id))conn.commit()

cursor.rowcount可以拿到受影响的行数:

returncursor.rowcount

如果返回1,说明成功修改了一条记录;如果返回0,说明没有找到对应 ID 的学生。

6. 删除数据

sql="DELETE FROM students WHERE id = ?;"cursor=conn.execute(sql,(student_id,))conn.commit()

删除操作也要记得调用commit(),否则修改不会真正保存到数据库文件。

六、commit 为什么重要

SQLite 的插入、修改、删除都属于写操作。执行写操作后,需要调用:

conn.commit()

如果不提交事务,程序结束后数据可能不会保存。

常见规律:

  • SELECT查询:不需要commit()
  • INSERT新增:需要commit()
  • UPDATE修改:需要commit()
  • DELETE删除:需要commit()

七、使用 with 自动管理连接

示例代码里使用了:

withget_connection()asconn:create_table(conn)

这样可以让数据库连接的生命周期更清晰。代码块执行完成后,连接会被正确处理。对于小型脚本来说,这种写法简单、直观,也能减少忘记关闭连接的问题。

如果你不使用with,也可以这样写:

conn=get_connection()try:create_table(conn)finally:conn.close()

八、常见错误总结

1. 忘记提交事务

conn.execute("INSERT INTO students ...")

只执行 SQL 还不够,写操作后要加:

conn.commit()

2. 单参数元组忘记逗号

错误写法:

conn.execute("SELECT * FROM students WHERE id = ?",(student_id))

正确写法:

conn.execute("SELECT * FROM students WHERE id = ?",(student_id,))

3. 直接拼接 SQL

错误写法:

sql=f"SELECT * FROM students WHERE name = '{name}'"

正确写法:

sql="SELECT * FROM students WHERE name = ?"conn.execute(sql,(name,))

九、可以继续扩展的方向

学会这个基础版本后,可以继续尝试:

  1. 增加命令行菜单,让用户输入选项操作数据库
  2. 增加异常处理,例如捕获数据库执行错误
  3. 增加更多字段,例如手机号、创建时间
  4. 把数据库操作封装成一个StudentRepository
  5. 使用 Flask 或 FastAPI 做一个简单的 Web 接口

十、总结

Python 操作 SQLite 的核心流程可以总结为:

连接数据库 -> 创建表 -> 执行 SQL -> 提交事务 -> 查询结果 -> 关闭连接

最常用的几个方法是:

方法作用
sqlite3.connect()连接数据库
conn.execute()执行 SQL
conn.commit()提交事务
fetchone()查询一条记录
fetchall()查询多条记录
conn.close()关闭连接

SQLite 轻量、免安装、上手快,非常适合 Python 新手练习数据库的增删改查。掌握本文这个小项目后,再去学习 MySQL、PostgreSQL 或 ORM 框架,会更容易理解数据库操作的底层逻辑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 13:36:20

Nginx反向代理SSE长连接:配置优化与性能调优实战

1. 为什么需要Nginx反向代理SSE长连接 最近在做一个实时数据监控项目时,遇到了一个棘手的问题:当有大量客户端同时连接SSE服务时,后端服务器直接崩溃了。这让我意识到,像SSE这样的长连接服务,如果没有合适的代理层做缓…

作者头像 李华
网站建设 2026/4/21 13:34:59

如何用Applite在10分钟内告别Mac软件安装的烦恼?

如何用Applite在10分钟内告别Mac软件安装的烦恼? 【免费下载链接】Applite User-friendly GUI macOS application for Homebrew Casks 项目地址: https://gitcode.com/gh_mirrors/ap/Applite 还在为Mac上繁琐的软件安装流程而头疼吗?Applite作为一…

作者头像 李华
网站建设 2026/4/21 13:34:17

LumenPnP开源贴片机终极指南:打造你的专属自动化电子组装系统

LumenPnP开源贴片机终极指南:打造你的专属自动化电子组装系统 【免费下载链接】lumenpnp The LumenPnP is an open source pick and place machine. 项目地址: https://gitcode.com/gh_mirrors/lu/lumenpnp 想象一下,你只需花费传统商用设备十分之…

作者头像 李华
网站建设 2026/4/21 13:28:16

VUE--项目问题

1. useRouter()&#xff1a;拿到路由器&#xff0c;可以查看路由以及使用路由器的方法们2. <el-menu-item v-for"item in router.options.routes[0].children" :index"item.path">router.options.routes[0].children 这个是路由表里的第一个路…

作者头像 李华