76·模块十四:数据库操作进阶

轻量级 ORM:Peewee 入门

databasesormpeewee

第76课:轻量级 ORM:Peewee 入门

1. 学习目标

通过本课学习,你将能够:

  • 理解 ORM 的概念及其在 Python 中的作用。
  • 掌握 Peewee 的安装、配置及基本使用方法。
  • 使用 Peewee 定义数据模型,并完成对数据库的增删改查(CRUD)操作。
  • 了解 Peewee 与不同数据库后端(如 SQLite、MySQL、PostgreSQL)的连接配置。

2. 核心概念

什么是 ORM?

ORM(Object-Relational Mapping,对象关系映射)是一种技术,它允许我们使用面向对象的 Python 代码来操作数据库,而不需要直接编写 SQL 语句。你可以把 ORM 想象成一个"翻译官":你告诉它"给我所有名为'张三'的用户",它就去数据库里执行 SELECT * FROM user WHERE name='张三' 并把结果返回给你。

为什么选择 Peewee?

在 Python 中,Django ORM、SQLAlchemy 是功能强大且广为人知的 ORM 库。而 Peewee 是一个追求 轻量、简洁、易用 的 ORM。它非常适合:

  • 中小型项目。
  • 快速原型开发。
  • 学习 ORM 的核心概念。
  • 不需要庞大框架,但希望用优雅的方式操作数据库的场景。

核心概念图解

  1. 模型类 (Model):对应数据库中的一张表。用 Python 类定义。
  2. 字段 (Field):模型类中的属性,对应表中的列(如 CharField, IntegerField)。
  3. 实例 (Instance):模型类的一个对象,对应表中的一行数据。
  4. 查询 (Query):通过模型类的方法生成,用于获取、修改或删除数据。

3. 代码示例

以下示例使用内置的 SQLite 数据库,无需额外安装数据库服务器。

# 1. 安装 Peewee
# 在终端运行: pip install peewee

# 2. 导入必要的模块
from peewee import *

# 3. 定义数据库连接(这里使用 SQLite)
# 数据库文件名为 `my_app.db`,如果不存在会自动创建
db = SqliteDatabase('my_app.db')

# 4. 定义基础模型类(可选,但推荐)
# 它可以让其他模型继承这个数据库连接配置,避免重复代码
class BaseModel(Model):
    class Meta:
        database = db

# 5. 定义具体的数据模型
class User(BaseModel):
    # 定义字段:自增主键、用户名(唯一)、邮箱、注册时间
    id = AutoField(primary_key=True)
    username = CharField(unique=True, max_length=50)
    email = CharField(null=True)  # 允许为空
    join_date = DateTimeField(constraints=[SQL('DEFAULT CURRENT_TIMESTAMP')])

    class Meta:
        table_name = 'users'  # 指定表名,不写则默认为 'user'(小写类名)

class Tweet(BaseModel):
    # 定义一个简单的"推文"模型
    user = ForeignKeyField(User, backref='tweets')  # 外键关联到 User, `backref` 允许通过 user.tweets 访问
    content = TextField()
    timestamp = DateTimeField(constraints=[SQL('DEFAULT CURRENT_TIMESTAMP')])

# 6. 连接数据库并创建表
db.connect()
# 创建表(如果不存在),`safe=True` 表示如果表已存在则跳过,不会报错
db.create_tables([User, Tweet])

# === 以下是 CRUD 操作示例 ===

# --- 创建(Create)---
# 创建一个用户实例并保存
new_user = User.create(username='alice', email='[email protected]')
print(f"创建用户: ID={new_user.id}, 用户名={new_user.username}")

# 创建一条推文,关联到 alice
alice = User.get(User.username == 'alice') # 先获取 alice 的实例
Tweet.create(user=alice, content='Hello, this is my first tweet!')

# --- 查询(Read)---
# 获取所有用户
all_users = User.select()
for user in all_users:
    print(f"用户: {user.username}, 邮箱: {user.email}")

# 条件查询:获取用户名为'alice'的用户
alice = User.get(User.username == 'alice')
print(f"找到了 Alice: {alice.email}")

# 获取 alice 的所有推文 (使用 backref)
print("Alice 的推文:")
for tweet in alice.tweets:  # `tweets` 就是之前在 ForeignKeyField 中定义的 backref
    print(f"  - {tweet.content} (时间: {tweet.timestamp})")

# --- 更新(Update)---
# 更新 alice 的邮箱
alice.email = '[email protected]'
alice.save()  # 必须调用 .save() 方法才能保存更改
print(f"更新后的 Alice 邮箱: {User.get(User.username == 'alice').email}")

# --- 删除(Delete)---
# 删除一条推文
first_tweet = Tweet.get()  # 获取第一条推文
print(f"删除推文: {first_tweet.content}")
first_tweet.delete_instance()

# 关闭数据库连接(良好的实践)
db.close()

运行后,数据库中将有 userstweet 两张表,并完成了增删改查的演示。

4. 实践练习

练习一:修改与更新

  1. 创建一个新用户 bob,邮箱为 [email protected]
  2. bob 发布两条内容不同的推文。
  3. 查询 bob 的所有推文并打印其内容。

练习二:条件删除

  1. 编写代码,删除 User 表中所有邮箱为空的用户。
  2. 删除后,查询并打印剩余用户列表,验证操作是否成功。

练习三:模型设计

  1. 设计一个 Product (商品) 模型,包含字段:商品名称、价格(小数)、库存数量、上架状态(布尔值)。
  2. 使用 Peewee 创建这个表。
  3. 插入一条测试数据(例如:商品名 "Python书",价格 49.99,库存 100,状态为 True)。

5. 常见错误

  1. 忘记 save():修改了模型实例的属性后,必须调用 .save(),否则更改不会持久化到数据库。

    user.username = 'new_name'
    # user.save()  # 忘了这行,数据库不会改变!
    
  2. 字段名与 Python 关键字冲突:如果字段名是 Python 关键字(如 type, class),需要使用 db_column 参数重命名。

    class Article(BaseModel):
        type_ = CharField(max_length=20, db_column='type')  # 数据库列名为 'type'
    
  3. 查询未调用 .execute() 或迭代User.select() 返回的是一个查询对象,只有在迭代(如 for user in query)或调用 .execute() 时才会真正执行查询。

  4. 外键关联错误:定义 ForeignKeyField 时,model 参数应指向另一个模型类,而不是字符串。如果需要自关联,需要特殊处理。

  5. 数据库未创建就操作:确保在插入数据前,已经调用了 db.connect()db.create_tables()

6. 小结

本课我们学习了:

  • ORM 的价值:它让我们用操作 Python 对象的方式来与数据库交互,提升开发效率和代码可维护性。
  • Peewee 的核心三要素
    1. 数据库连接 (SqliteDatabase, PostgresqlDatabase等)。
    2. 模型定义 (继承 Model 的类,包含 Field)。
    3. 数据库表创建 (create_tables)。
  • 基本 CRUD 操作
    • Model.create()instance.save()
    • Model.select(), Model.get()
    • :修改实例属性后调用 instance.save()
    • instance.delete_instance()
  • 外键关联:使用 ForeignKeyField 建立模型间关系,并通过 backref 反向访问。

掌握了 Peewee 的基础,你就拥有了用 Python 代码优雅管理数据的强大工具。在下一课,我们将转向一个全新的领域——使用 Tkinter 构建图形用户界面(GUI)程序。

练习编辑器

python
Loading...

继续学习

完成本课后,建议继续学习下一课「GUI 编程入门:Tkinter 简介」 以巩固所学知识。