27、Python 数据库操作入门(SQLite)从基础到实战精讲

Python 数据库操作入门(SQLite)从基础到实战精讲

引言

本文针对Python操作SQLite数据库进行系统化讲解,涵盖连接管理、游标控制、CRUD操作、事务处理、SQL注入防护等核心内容。通过学生信息管理系统案例,演示实际开发场景中的技术应用,并提供索引优化、备份恢复等高级技巧。读者将掌握安全高效的数据库操作范式,并具备解决复杂业务需求的能力。


一、SQLite核心概念

1.1 SQLite特点

  • 无服务器、零配置的嵌入式关系型数据库
  • 单文件存储(.db或内存模式)
  • 支持ACID事务,最大支持281TB数据

1.2 连接与游标

python 复制代码
import sqlite3

# 创建内存数据库(测试用)或文件数据库
conn = sqlite3.connect(':memory:')  # 文件模式:'students.db'
cursor = conn.cursor()  # 获取操作游标

注意事项

  1. 连接对象需显式关闭conn.close()
  2. 游标用于执行SQL并获取结果集
  3. 内存数据库在连接关闭后数据丢失

二、CRUD基础操作

2.1 表结构创建

python 复制代码
# 创建学生表(包含事务控制)
try:
    cursor.execute('''CREATE TABLE IF NOT EXISTS students (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    age INTEGER CHECK(age>0),
                    gender CHAR(1) DEFAULT 'M',
                    created TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''')
    conn.commit()
except sqlite3.Error as e:
    conn.rollback()
    print(f"创建表失败: {e}")

字段约束说明

  • PRIMARY KEY:自增主键
  • CHECK:年龄必须>0
  • DEFAULT:默认值设置

2.2 数据插入

单条插入(防注入写法)

python 复制代码
# 参数化查询(问号占位符)
data = ('王小明', 18, 'M')
cursor.execute("INSERT INTO students (name, age, gender) VALUES (?, ?, ?)", data)

# 获取自增ID
print(f"插入记录的ID: {cursor.lastrowid}")  

批量插入(executemany)

python 复制代码
batch_data = [('李雷', 17, 'M'), ('韩梅梅', 16, 'F')]
cursor.executemany("INSERT INTO students (name, age, gender) VALUES (?,?,?)", batch_data)
conn.commit()  # 显式提交事务

2.3 查询与结果集处理

python 复制代码
# 获取全部结果
cursor.execute("SELECT * FROM students WHERE age > ?", (15,))
all_rows = cursor.fetchall()

# 逐行获取(内存友好)
cursor.execute("SELECT name, age FROM students")
while True:
    row = cursor.fetchone()
    if not row: break
    print(f"姓名:{row[0]}, 年龄:{row[1]}")

2.4 更新与删除

python 复制代码
# 更新操作
cursor.execute("UPDATE students SET age=? WHERE name=?", (19, '王小明'))

# 删除操作
cursor.execute("DELETE FROM students WHERE id=?", (5,))
conn.commit()

三、高级技巧与安全

3.1 参数化查询必要性

危险写法(SQL注入漏洞)

python 复制代码
name = input("输入姓名:")
# 恶意输入:' OR 1=1 --
cursor.execute(f"SELECT * FROM students WHERE name='{name}'")

安全写法

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

3.2 事务控制实践

python 复制代码
try:
    # 开始事务(SQLite默认自动提交关闭)
    cursor.execute("BEGIN TRANSACTION")
    
    # 业务操作1
    cursor.execute("UPDATE account SET balance=balance-100 WHERE user_id=1")
    
    # 业务操作2 
    cursor.execute("UPDATE account SET balance=balance+100 WHERE user_id=2")
    
    conn.commit()  # 提交事务
except:
    conn.rollback()  # 回滚所有操作

3.3 使用上下文管理器

python 复制代码
with sqlite3.connect('students.db') as conn:
    cursor = conn.cursor()
    # 操作自动提交或回滚

四、性能优化方案

4.1 索引优化

python 复制代码
# 创建索引(提升查询速度)
cursor.execute("CREATE INDEX idx_students_age ON students(age)")

# 查看执行计划
cursor.execute("EXPLAIN QUERY PLAN SELECT * FROM students WHERE age>18")
print(cursor.fetchall())

4.2 备份与恢复

命令行方式

bash 复制代码
sqlite3 students.db ".dump" > backup.sql  # 备份
sqlite3 restored.db < backup.sql         # 恢复

Python实现增量备份

python 复制代码
def backup_db(src, dest):
    with sqlite3.connect(src) as src_conn:
        with sqlite3.connect(dest) as dest_conn:
            src_conn.backup(dest_conn)

五、综合案例:学生管理系统

python 复制代码
class StudentDB:
    def __init__(self, db_path):
        self.conn = sqlite3.connect(db_path)
        self.create_table()
    
    def create_table(self):
        # 创建表结构(略)
    
    def add_student(self, name, age, gender):
        # 参数化插入(防注入)
    
    def query_by_age_range(self, min_age, max_age):
        # 返回年龄区间的学生
    
    # 其他方法:update/delete/statistics...

# 使用示例
db = StudentDB('students.db')
db.add_student('张伟', 20, 'M')
results = db.query_by_age_range(15, 20)

六、练习题

  1. 索引优化 :为created字段创建索引,分析查询性能变化
  2. 复杂查询:编写联表查询(班级表+学生表),统计各班人数
  3. 事务测试:模拟批量插入1万条数据,对比有无事务的性能差异
  4. 备份脚本:编写Python定时备份脚本,保留最近7天备份

总结与扩展

本文详细讲解了SQLite在Python中的完整操作流程,从基础连接到高级优化均给出实践方案。建议进一步学习:

  • 数据库连接池技术(如SQLAlchemy
  • ORM框架的使用(Peewee/Django ORM
  • SQLite的WAL模式配置
  • 数据库迁移工具(Alembic
相关推荐
山甫aa30 分钟前
JavaWeb后端开发学习手册
java·开发语言·数据库·学习·mysql·springboot·web
JavaPub-rodert40 分钟前
MongoDB 常用命令和常见问题大全
数据库·mongodb
ly768941 分钟前
XML 从入门到实践:语法、命名空间、XPath、XSD 与 Java 安全解析
xml·java·python
winfredzhang1 小时前
用 Python + wxPython 造一个照片工具箱:PDF / 加密ZIP / MP4 / 归档,以及我在这过程中踩到的 4 个坑
python·pdf·zip·mp4·移动
卷无止境1 小时前
FastAPI 后台任务的边界,以及 Celery、Redis 与自建调度系统的选择
后端·python
卷无止境1 小时前
Linux + Docker + FastAPI 工程化实践指南
后端·python·fastapi
Dovis(誓平步青云)2 小时前
从Redis指标采集到异常告警:redis_exporter + Prometheus 完整实战
服务器·数据库·人工智能·redis·架构·prometheus·vibe coding
城管不管10 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
倔强的石头10610 小时前
向量数据库从相似度检索走向融合数据底座
数据库