SQLite数据库 - 教程

一、SQLite 简介

QLite 是一个轻量级、嵌入式、无服务器的关系型数据库,适用于小型项目、移动应用、测试环境等场景。Python 内置 sqlite3 模块,无需安装即可使用。

特点:

  • 无需独立服务器,数据库存储在单一文件中

  • 支持标准 SQL 语法

  • 跨平台、高性能、易于集成

二、数据存储方式对比

方式存储位置是否持久化适用场景
变量内存临时数据、程序运行时
文件磁盘JSON/CSV/TXT/Excel 等
数据库磁盘结构化数据、复杂查询

三、SQLite 操作方式

1、原生 SQL 语句操作(基础方式)

操作流程:

  1. 导入 sqlite3 模块

  2. 连接数据库:conn = sqlite3.connect('db_name.db')

  3. 创建游标:cur = conn.cursor()

  4. 执行 SQL 语句:cur.execute(sql)

  5. 提交事务:conn.commit()

  6. 关闭连接: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%';

示例:

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

关键细节与注意事项

  1. SQL注入防护永远不要使用字符串拼接的方式构造 SQL 语句(如 f"SELECT * FROM users WHERE name = '{user_input}'")。务必使用参数化查询(? 占位符)。

  2. 事务管理

    • conn.commit():提交当前事务,使更改永久化。

    • conn.rollback():回滚当前事务,撤销所有未提交的更改。

    • 对于写操作(INSERT, UPDATE, DELETE),必须在操作后调用 commit()

  3. 连接管理

    • 使用 with 语句可以自动管理连接的关闭:

      with sqlite3.connect('example.db') as conn:
          cursor = conn.cursor()
          # ... 操作数据库
      # 离开 with 块后连接自动关闭
  4. 结果获取方法

    • fetchone():获取下一行。

    • fetchall():获取所有行。

    • fetchmany(size):获取指定数量的行。

  5. 数据类型映射

    • SQLite 数据类型会自动映射到 Python 类型(TEXT→str, INTEGER→int, REAL→float, BLOB→bytes)。

2、ORM 操作(推荐用于项目开发)

操作流程:

1.安装依赖:

pip install fastapi sqlalchemy uvicorn

2.导入模块:

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base

3.创建引擎和会话:

engine = create_engine("sqlite:///test.db")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

4.定义数据模型:

class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True)
age = Column(Integer)

5.创建表:

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

示例:

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""
# 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()

关键细节与注意事项

  1. 会话生命周期

    • 会话(Session)相当于 SQLite 中的连接,但功能更强大。

    • 会话跟踪对象的更改,实现工作单元模式。

  2. 对象状态

    • Transient:对象存在,但不在会话中,未保存到数据库。

    • Pending:对象已添加到会话,但未刷新到数据库。

    • Persistent:对象已在数据库中,与会话关联。

    • Detached:对象曾在数据库中,但已与会话分离。

  3. 查询方法

    • all():返回所有结果的列表。

    • first():返回第一个结果,如果没有则返回 None。

    • one():返回一个结果,如果不是恰好一个则抛出异常。

    • count():返回结果数量。

  4. 关系映射

    • SQLAlchemy 支持定义表之间的关系(一对一、一对多、多对多)。

    • 使用 relationship() 定义关系,ForeignKey 定义外键。

  5. 性能优化

    • 使用 lazy='joined' 或 lazy='subquery' 优化关联数据的加载。

    • 对于大量数据,使用 yield_per() 进行流式处理。

四、总结

特性原生 SQL (sqlite3)ORM (SQLAlchemy)
学习曲线需要熟悉 SQL需要学习 ORM 概念
灵活性非常高,可执行任意 SQL较高,但复杂查询可能仍需 SQL
安全性需手动防止 SQL 注入自动防止 SQL 注入
可维护性较低,SQL 与代码混合较高,面向对象,代码清晰
开发效率较低较高,特别是 CRUD 操作
适用场景简单脚本、性能关键操作中大型项目、团队开发

posted @ 2025-09-21 09:20  wzzkaifa  阅读(35)  评论(0)    收藏  举报