Python ORM编程基础:原理、CRUD与Peewee实战

山间有风
山间有风
发布时间:2026-10-13 | 2人浏览过
原创

本文深入解析Python ORM(对象关系映射)的核心原理,涵盖数据类型、类及关系的映射机制。详细阐述ORM如何自动处理增删改查(CRUD)及缓存优化,并通过Peewee库展示从建表、外键关联到复杂查询的完整实战代码,帮助开发者高效进行数据库编程。

本文通过具体实例介绍Python中的ORM编程技术,旨在为读者提供可参考的学习资料。

ORM编程概述

ORM编程概述

ORM(Object-Relational Mapping,对象关系映射)的主要作用是在关系型数据库与业务实体对象之间建立映射关系。其核心价值在于简化开发流程,使开发者无需编写复杂的SQL语句,仅需通过操作对象的属性和方法即可完成数据交互。所有ORM框架均具备三项基本能力:映射技术、CRUD(增删改查)操作以及缓存优化。不同编程语言拥有各自的ORM库,例如Java的Hibernate和IBATIS、C#的Grove LINQ,以及Python的SQLAlchemy等。

映射技术原理

1、映射技术

面向对象编程源于软件工程的基本原则,如耦合、聚合和封装;而关系型数据库则建立在数学理论的基础之上。ORM旨在弥合这两种范式之间的差异。

ORM库需要解决以下三个核心问题:

  • 数据类型映射:将数据库中的字段类型转换为编程语言中对应的数据类型。
  • 类映射:将数据库中的表结构定义映射为编程语言中的类定义。
  • 关系映射:将数据库中基于外键的连接关系,转换为编程语言中基于对象引用的关联关系。

CRUD操作流程

2、CRUD操作

  • C – Create(创建/增加)
  • R – Retrieve(读取,即从数据库重新获取数据)
  • U – Update(更新)
  • D – Delete(删除)

在原生SQL中,通常使用insert、select、update和delete四种语句来实现CRUD功能。

ORM框架会自动实现以下操作流程:

  1. 将高级语言的调用转换为标准的SQL语句。
  2. 通过数据库引擎将SQL语句发送给数据库执行。
  3. 将数据库返回的结果集,利用映射技术转换回编程语言中的类对象。

缓存优化机制

3、缓存优化

  • 将从数据库查询到的数据以类对象的形式保存在本地内存中,以便后续使用时可以直接抽取,无需再次访问数据库。
  • 真正的数据库select操作仅在真正需要读取查询结果时执行,而不是在ORM查询命令发出时立即查询数据库,从而提升性能。

Peewee实战示例

4、使用Peewee进行ORM数据库编程

实现思路如下:

  • 导入必要的包(如peewee),并建立一个数据库引擎对象db。
  • 定义一个ORM基类BaseModel(),建立与SQLite数据库的连接。
  • 进行类型映射:定义所需的数据类型字段。
  • 进行表映射:定义两个对象类,分别为course和teacher。
  • 进行关系映射:使用ForeignKeyField设置与course的连接关系。其中,to_field参数用于指定被连接的字段名,related_name参数为该关系赋予一个名称。

import os
if os.path.exists('sampleDB.db'):
  os.remove('sampleDB.db')
# 引入peewee包的所有内容
from peewee import *
# 建立一个Sqlite数据库引擎对象,该引擎打开数据库文件sampleDB.db
db = SqliteDatabase("sampleDB.db")
# 定义一个ORM的基类,在基类中指定本ORM所使用的数据库,
# 这样在之后所有的子类中就不用重复声明数据库
class BaseModel(Model):
  class Meta:
    database = db
# 定义course表,继承自BaseModel
class Course(BaseModel):
  id = PrimaryKeyField() # 定义主键
  title = CharField(null=False) # 定义字符串
  period = IntegerField() # 整型
  description = CharField()
  class Meta:
    order_by = ('title',)
    db_table = 'course'  # 定义数据库中的表名
# 定义 teacher 表,继承自BaseModel
class Teacher(BaseModel):
  id = PrimaryKeyField()
  name = CharField(null=False)
  gender = BooleanField() # 布尔型
  address = CharField()
  # ForeignKeyField 设置与course的连接关系,其中的参数:to_field用于指定被连接的字段名,related_name参数对该关系赋予了一个名字
  course_id = ForeignKeyField(Course, to_field="id", related_name="course")
  class Meta:
    order_by = ('name',)
    db_table = "teacher"
# 建表,仅需创建一次
Course.create_table()
Teacher.create_table()
# 新增行
Course.create(id=1, title='经济学', period=320, description='文理科学生均可选修')
Course.create(id=2, title='大学英语', period=300, description='大一学生必修课')
Course.create(id=3, title='哲学', period=100, description='必修课')
Course.create(id=134, title='编译原理', period=100, description='计算机系选修')
Teacher.create(name='白阵君', gender=True, address='..', course_id=1)
Teacher.create(name='李森', gender=True, address='..', course_id=3)
Teacher.create(name='张雯雯', gender=False, address='..', course_id=2)
# 查询一行
record = Course.get(Course.title == '大学英语')
print("课程:%s, 学时:%d, 课程类型: %s" % (record.title, record.period, record.description))
# 更新
record.period = 200
record.save()
# 删除
record.delete_instance()
# 查询所有记录
courses = Course.select()
for i in courses:
  print(i.id, i.title, i.period, i.description)
# 带条件查询,并将结果按period字段倒序排序
courses = Course.select().where(Course.id< 10).order_by(Course.period.desc())
for i in courses:
  print(i.id, i.title, i.period, i.description)
# 统计所有课程的平均学时
total = Course.select(fn.Avg (Course.period).alias('avg_period'))
for i in total:
  print(u"平均学时:", i.avg_period)
# 更新多个记录
Course.update(period=300).where(Course.id > 100).execute()
# 多表连接操作,Peewee会自动根据ForeignKeyField的外键定义进行连接:
Record = Course.select().join(Teacher).where(Teacher.gender == True)
for i in Record:
  print(i.id, i.title, i.period, i.description)

参考来源:书籍《python 高效开发实战》。

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python常见数据库操作技巧汇总》、《Python数学运算技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》。

希望本文所述内容对大家学习Python程序设计有所帮助。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表