Python 数据库操作入门(SQLite)从基础到实战精讲
引言
本文针对Python操作SQLite数据库进行系统化讲解,涵盖连接管理、游标控制、CRUD操作、事务处理、SQL注入防护等核心内容。通过学生信息管理系统案例,演示实际开发场景中的技术应用,并提供索引优化、备份恢复等高级技巧。读者将掌握安全高效的数据库操作范式,并具备解决复杂业务需求的能力。
一、SQLite核心概念
1.1 SQLite特点
- 无服务器、零配置的嵌入式关系型数据库
- 单文件存储(
.db
或内存模式) - 支持ACID事务,最大支持281TB数据
1.2 连接与游标
import sqlite3
# 创建内存数据库(测试用)或文件数据库
conn = sqlite3.connect(':memory:') # 文件模式:'students.db'
cursor = conn.cursor() # 获取操作游标
注意事项:
- 连接对象需显式关闭
conn.close()
- 游标用于执行SQL并获取结果集
- 内存数据库在连接关闭后数据丢失
二、CRUD基础操作
2.1 表结构创建
# 创建学生表(包含事务控制)
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
:年龄必须>0DEFAULT
:默认值设置
2.2 数据插入
单条插入(防注入写法)
# 参数化查询(问号占位符)
data = ('王小明', 18, 'M')
cursor.execute("INSERT INTO students (name, age, gender) VALUES (?, ?, ?)", data)
# 获取自增ID
print(f"插入记录的ID: {cursor.lastrowid}")
批量插入(executemany)
batch_data = [('李雷', 17, 'M'), ('韩梅梅', 16, 'F')]
cursor.executemany("INSERT INTO students (name, age, gender) VALUES (?,?,?)", batch_data)
conn.commit() # 显式提交事务
2.3 查询与结果集处理
# 获取全部结果
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 更新与删除
# 更新操作
cursor.execute("UPDATE students SET age=? WHERE name=?", (19, '王小明'))
# 删除操作
cursor.execute("DELETE FROM students WHERE id=?", (5,))
conn.commit()
三、高级技巧与安全
3.1 参数化查询必要性
危险写法(SQL注入漏洞)
name = input("输入姓名:")
# 恶意输入:' OR 1=1 --
cursor.execute(f"SELECT * FROM students WHERE name='{name}'")
安全写法
cursor.execute("SELECT * FROM students WHERE name=?", (name,))
3.2 事务控制实践
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 使用上下文管理器
with sqlite3.connect('students.db') as conn:
cursor = conn.cursor()
# 操作自动提交或回滚
四、性能优化方案
4.1 索引优化
# 创建索引(提升查询速度)
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 备份与恢复
命令行方式
sqlite3 students.db ".dump" > backup.sql # 备份
sqlite3 restored.db < backup.sql # 恢复
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)
五、综合案例:学生管理系统
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)
六、练习题
- 索引优化:为
created
字段创建索引,分析查询性能变化 - 复杂查询:编写联表查询(班级表+学生表),统计各班人数
- 事务测试:模拟批量插入1万条数据,对比有无事务的性能差异
- 备份脚本:编写Python定时备份脚本,保留最近7天备份
总结与扩展
本文详细讲解了SQLite在Python中的完整操作流程,从基础连接到高级优化均给出实践方案。建议进一步学习:
- 数据库连接池技术(如
SQLAlchemy
) - ORM框架的使用(
Peewee
/Django ORM
) - SQLite的WAL模式配置
- 数据库迁移工具(
Alembic
)