一、SQLite 简介
QLite 是一个轻量级、嵌入式、无服务器 的关系型数据库,适用于小型项目、移动应用、测试环境等场景。Python 内置 sqlite3
模块,无需安装即可使用。
特点:
-
无需独立服务器,数据库存储在单一文件中
-
支持标准 SQL 语法
-
跨平台、高性能、易于集成
二、数据存储方式对比
方式 | 存储位置 | 是否持久化 | 适用场景 |
---|---|---|---|
变量 | 内存 | 否 | 临时数据、程序运行时 |
文件 | 磁盘 | 是 | JSON/CSV/TXT/Excel 等 |
数据库 | 磁盘 | 是 | 结构化数据、复杂查询 |
三、SQLite 操作方式
1、原生 SQL 语句操作(基础方式)
操作流程:
-
导入
sqlite3
模块 -
连接数据库:
conn = sqlite3.connect('db_name.db')
-
创建游标:
cur = conn.cursor()
-
执行 SQL 语句:
cur.execute(sql)
-
提交事务:
conn.commit()
-
关闭连接:
conn.close()
常用 SQL 语句:
操作 | SQL 示例 |
---|---|
创建表 | CREATE TABLE table_name (id INTEGER PRIMARY KEY, name TEXT NOT NULL); |
删除表 | DROP TABLE table_name; |
插入数据 | INSERT INTO table_name (name, age) VALUES (?, ?); |
查询数据 | SELECT * FROM table_name; |
更新数据 | UPDATE table_name SET age = 30 WHERE name = 'Alice'; |
删除数据 | DELETE FROM table_name WHERE id = 1; |
模糊查询 | SELECT * FROM table_name WHERE name LIKE '%Alice%'; |
示例:
python
import sqlite3
# 1. 连接到数据库(如果不存在则创建)
# 注意:连接对象是线程不安全的,每个线程应创建自己的连接。
conn = sqlite3.connect('example.db') # 数据库存储在 example.db 文件中
# 可以使用 ':memory:' 创建内存数据库,仅程序运行时存在
# conn = sqlite3.connect(':memory:')
# 2. 创建游标对象
# 游标是用于执行 SQL 命令和获取结果的主要对象
cursor = conn.cursor()
try:
# 3. 执行 SQL 语句 - 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT, -- 自增主键
username TEXT NOT NULL UNIQUE, -- 用户名,不能重复
email TEXT, -- 邮箱,可为空
age INTEGER, -- 年龄
created_at DATETIME DEFAULT CURRENT_TIMESTAMP -- 创建时间,自动设置
)
''')
# 4. 插入数据 - 安全的方式(防止SQL注入)
# 使用 ? 作为占位符,参数以元组形式传入
user_data = ('alice', 'alice@example.com', 25)
cursor.execute('INSERT INTO users (username, email, age) VALUES (?, ?, ?)', user_data)
# 插入多条数据
users_list = [
('bob', 'bob@example.com', 30),
('charlie', 'charlie@example.com', 35),
('diana', None, 28) # email 为 NULL
]
cursor.executemany('INSERT INTO users (username, email, age) VALUES (?, ?, ?)', users_list)
# 5. 查询数据
# 查询所有数据
cursor.execute('SELECT * FROM users')
all_users = cursor.fetchall() # 获取所有记录,返回列表元组
print("All users:")
for user in all_users:
print(user)
# 查询单条数据
cursor.execute('SELECT * FROM users WHERE username = ?', ('alice',))
alice = cursor.fetchone() # 获取单条记录
print(f"\nAlice's data: {alice}")
# 6. 更新数据
cursor.execute('UPDATE users SET age = ? WHERE username = ?', (26, 'alice'))
print(f"Updated {cursor.rowcount} row(s)")
# 7. 删除数据
cursor.execute('DELETE FROM users WHERE username = ?', ('charlie',))
print(f"Deleted {cursor.rowcount} row(s)")
# 8. 提交事务 - 非常重要!
# 确保所有的更改被永久保存到数据库
conn.commit()
print("Transaction committed successfully")
except sqlite3.Error as e:
# 9. 如果出现错误,回滚事务
print(f"Database error: {e}")
conn.rollback()
finally:
# 10. 关闭连接 - 释放资源
cursor.close()
conn.close()
print("Database connection closed")

关键细节与注意事项
-
SQL注入防护 :永远不要 使用字符串拼接的方式构造 SQL 语句(如
f"SELECT * FROM users WHERE name = '{user_input}'"
)。务必使用参数化查询(?
占位符)。 -
事务管理:
-
conn.commit()
:提交当前事务,使更改永久化。 -
conn.rollback()
:回滚当前事务,撤销所有未提交的更改。 -
对于写操作(INSERT, UPDATE, DELETE),必须在操作后调用
commit()
。
-
-
连接管理:
-
使用
with
语句可以自动管理连接的关闭:with sqlite3.connect('example.db') as conn: cursor = conn.cursor() # ... 操作数据库 # 离开 with 块后连接自动关闭
-
-
结果获取方法:
-
fetchone()
:获取下一行。 -
fetchall()
:获取所有行。 -
fetchmany(size)
:获取指定数量的行。
-
-
数据类型映射:
- SQLite 数据类型会自动映射到 Python 类型(TEXT→str, INTEGER→int, REAL→float, BLOB→bytes)。
2、ORM 操作(推荐用于项目开发)
操作流程:
1.安装依赖:
python
pip install fastapi sqlalchemy uvicorn
2.导入模块:
python
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base
3.创建引擎和会话:
python
engine = create_engine("sqlite:///test.db")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
4.定义数据模型:
python
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True)
age = Column(Integer)
5.创建表:
python
Base.metadata.create_all(bind=engine)
6.使用会话进行 CRUD 操作
操作 | 方法示例 |
---|---|
插入 | db.add(user); db.commit() |
查询全部 | db.query(User).all() |
按条件查 | db.query(User).filter(User.name == "Alice").first() |
更新 | user.age = 25; db.commit() |
删除 | db.delete(user); db.commit() |
示例:
python
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker
# 1. 定义基类
Base = declarative_base()
# 2. 定义数据模型
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), unique=True, nullable=False)
email = Column(String(100))
age = Column(Integer)
def __repr__(self):
return f"<User(username='{self.username}')>"
# 3. 创建数据库引擎和会话工厂
engine = create_engine('sqlite:///simple_example.db')
SessionLocal = sessionmaker(bind=engine)
# 4. 创建表
Base.metadata.create_all(bind=engine)
# 5. 使用会话进行数据库操作
def main():
# 创建会话
db = SessionLocal()
try:
# 先清空表(简单示例中常用)
db.query(User).delete()
# 插入新数据
user1 = User(username='alice', email='alice@example.com', age=25)
user2 = User(username='bob', email='bob@example.com', age=30)
db.add(user1)
db.add(user2)
# 提交插入操作
db.commit()
# 查询所有用户
all_users = db.query(User).all()
print("所有用户:", all_users)
# 查询特定用户
alice = db.query(User).filter(User.username == 'alice').first()
print("Alice的信息:", alice)
# 更新数据
if alice:
alice.age = 26
db.commit()
print("更新后的Alice年龄:", alice.age)
# 删除数据
bob = db.query(User).filter(User.username == 'bob').first()
if bob:
db.delete(bob)
db.commit()
print("已删除Bob用户")
# 查看最终结果
remaining_users = db.query(User).all()
print("剩余用户:", remaining_users)
except Exception as e:
db.rollback()
print(f"发生错误: {e}")
finally:
db.close()
if __name__ == "__main__":
main()

关键细节与注意事项
-
会话生命周期:
-
会话(Session)相当于 SQLite 中的连接,但功能更强大。
-
会话跟踪对象的更改,实现工作单元模式。
-
-
对象状态:
-
Transient:对象存在,但不在会话中,未保存到数据库。
-
Pending:对象已添加到会话,但未刷新到数据库。
-
Persistent:对象已在数据库中,与会话关联。
-
Detached:对象曾在数据库中,但已与会话分离。
-
-
查询方法:
-
all()
:返回所有结果的列表。 -
first()
:返回第一个结果,如果没有则返回 None。 -
one()
:返回一个结果,如果不是恰好一个则抛出异常。 -
count()
:返回结果数量。
-
-
关系映射:
-
SQLAlchemy 支持定义表之间的关系(一对一、一对多、多对多)。
-
使用
relationship()
定义关系,ForeignKey
定义外键。
-
-
性能优化:
-
使用
lazy='joined'
或lazy='subquery'
优化关联数据的加载。 -
对于大量数据,使用
yield_per()
进行流式处理。
-
四、总结
特性 | 原生 SQL (sqlite3) | ORM (SQLAlchemy) |
---|---|---|
学习曲线 | 需要熟悉 SQL | 需要学习 ORM 概念 |
灵活性 | 非常高,可执行任意 SQL | 较高,但复杂查询可能仍需 SQL |
安全性 | 需手动防止 SQL 注入 | 自动防止 SQL 注入 |
可维护性 | 较低,SQL 与代码混合 | 较高,面向对象,代码清晰 |
开发效率 | 较低 | 较高,特别是 CRUD 操作 |
适用场景 | 简单脚本、性能关键操作 | 中大型项目、团队开发 |