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

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

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

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

一、项目目标

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

字段 类型 说明
id INTEGER 主键,自增
name TEXT 学生姓名
age INTEGER 年龄
major TEXT 专业
score REAL 分数

最终项目支持这些功能:

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

二、准备环境

确认本机已经安装 Python:

bash 复制代码
python --version

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

bash 复制代码
Python 3.11.0

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

三、项目结构

新建一个目录,例如:

text 复制代码
sqlite_crud_demo/
├── app.py
└── student.db

其中:

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

四、完整代码

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

python 复制代码
import sqlite3
from pathlib import Path


DB_PATH = Path(__file__).with_name("student.db")


def get_connection():
    """创建并返回数据库连接。"""
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def create_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()


def add_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()
    return cursor.lastrowid


def list_students(conn):
    """查询全部学生。"""
    sql = "SELECT id, name, age, major, score FROM students ORDER BY id;"
    return conn.execute(sql).fetchall()


def get_student_by_id(conn, student_id):
    """根据 ID 查询学生。"""
    sql = "SELECT id, name, age, major, score FROM students WHERE id = ?;"
    return conn.execute(sql, (student_id,)).fetchone()


def update_student_score(conn, student_id, new_score):
    """修改学生分数。"""
    sql = "UPDATE students SET score = ? WHERE id = ?;"
    cursor = conn.execute(sql, (new_score, student_id))
    conn.commit()
    return cursor.rowcount


def delete_student(conn, student_id):
    """删除学生。"""
    sql = "DELETE FROM students WHERE id = ?;"
    cursor = conn.execute(sql, (student_id,))
    conn.commit()
    return cursor.rowcount


def print_students(rows):
    """格式化输出查询结果。"""
    if not rows:
        print("暂无学生数据")
        return

    for row in rows:
        print(
            f"id={row['id']}, "
            f"name={row['name']}, "
            f"age={row['age']}, "
            f"major={row['major']}, "
            f"score={row['score']}"
        )


def main():
    with get_connection() as conn:
        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)
        if student:
            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()

运行程序:

bash 复制代码
python app.py

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

五、关键代码讲解

1. 连接 SQLite 数据库

python 复制代码
conn = sqlite3.connect(DB_PATH)

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

这里还设置了:

python 复制代码
conn.row_factory = sqlite3.Row

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

python 复制代码
row["name"]
row["score"]

这对新手更直观。

2. 创建数据表

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
);

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

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

3. 新增数据

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

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

推荐写法:

python 复制代码
conn.execute(sql, (name, age, major, score))

不推荐写法:

python 复制代码
sql = f"INSERT INTO students (name) VALUES ('{name}')"

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

4. 查询数据

查询全部学生:

python 复制代码
rows = conn.execute("SELECT * FROM students").fetchall()

查询单个学生:

python 复制代码
row = conn.execute(
    "SELECT * FROM students WHERE id = ?",
    (student_id,)
).fetchone()

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

5. 修改数据

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

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

python 复制代码
return cursor.rowcount

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

6. 删除数据

python 复制代码
sql = "DELETE FROM students WHERE id = ?;"
cursor = conn.execute(sql, (student_id,))
conn.commit()

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

六、commit 为什么重要

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

python 复制代码
conn.commit()

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

常见规律:

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

七、使用 with 自动管理连接

示例代码里使用了:

python 复制代码
with get_connection() as conn:
    create_table(conn)

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

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

python 复制代码
conn = get_connection()
try:
    create_table(conn)
finally:
    conn.close()

八、常见错误总结

1. 忘记提交事务

python 复制代码
conn.execute("INSERT INTO students ...")

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

python 复制代码
conn.commit()

2. 单参数元组忘记逗号

错误写法:

python 复制代码
conn.execute("SELECT * FROM students WHERE id = ?", (student_id))

正确写法:

python 复制代码
conn.execute("SELECT * FROM students WHERE id = ?", (student_id,))

3. 直接拼接 SQL

错误写法:

python 复制代码
sql = f"SELECT * FROM students WHERE name = '{name}'"

正确写法:

python 复制代码
sql = "SELECT * FROM students WHERE name = ?"
conn.execute(sql, (name,))

九、可以继续扩展的方向

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

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

十、总结

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

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

最常用的几个方法是:

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

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

相关推荐
2401_871696522 小时前
HTML怎么构建开发者仪表盘_HTML关键指标卡片汇总【教程】
jvm·数据库·python
2301_796588502 小时前
c++ aot编程 c++如何使用oneapi进行跨平台并行编程
jvm·数据库·python
草木红2 小时前
Python 中使用 Docker Compose
开发语言·python·docker·flask
qq_413847402 小时前
JavaScript中剩余参数在函数签名中的定义位置与限制
jvm·数据库·python
DavidSoCool2 小时前
Dify使用ChatFlow实现调用数据库问答
数据库·ai·知识库·dify
qq_330037992 小时前
mysql如何配置多实例运行环境_单机部署多个数据库服务
jvm·数据库·python
weixin_580614002 小时前
如何防止SQL注入泄露元数据_限制数据库信息查询权限
jvm·数据库·python
2301_777599372 小时前
mysql如何编写递归存储过程_mysql max_sp_recursion_depth设置
jvm·数据库·python
ofoxcoding2 小时前
GPT-5.4 API 怎么低延迟调用?2026 年 5 种接入方案实测对比
python·gpt·ai·flask