【ORM框架】Python ORM框架——peewee(详细)

article/2025/10/19 7:19:06

文章目录

  • 前言
  • 一、peewee的安装和入门
    • 1.字段类型表&Meta类型表&类型属性表
      • 字段类型表
      • Meta类型表
      • 类型属性表
    • 2.设计表结构
      • 防止连接丢失
  • 二、表的设计&操作
    • 0.继承
    • 1.添加
      • 生成表
      • 原生SQL
      • 添加
    • 2.查询
    • 3.更新
    • 4.删除
    • 5.约束
    • 6.复合主键
  • 三、详细操作
    • 1.like&排序&dict
    • 2.去重&统计
  • 四、避免n+1查询


前言

很多人对这个orm框架有很大的误区 以为会一个orm框架就不用去深入sql语句了 这会导致sql不会写 查询的时候实现困难 适应别的语言的orm框架还得再学一遍。
所以说sql一定一定要学好,这样查询实现的原理就会顺通,学习其他语言的orm框架就会快很多

ORM(Object Relational Mapping,对象关系映射),在Python下⾯有很多这样的类库,如
SQLObject、Storm、peewee和SQLAlchemy。

介绍⼀下Peewee的基本使⽤,因为它⾮常的轻量级,最主要是和Django的ORM 操作很像,如果你学过Django那么很容易上⼿。

一、peewee的安装和入门

peewee官方文档:http://docs.peewee-orm.com/en/latest/peewee/models.html

安装

pip install peewee
pip install pymysql

1.字段类型表&Meta类型表&类型属性表

字段类型表

可以看到对应关系 比如IntegerField 在mysql中是integer
在这里插入图片描述

Meta类型表

在这里插入图片描述

类型属性表

在这里插入图片描述

2.设计表结构

import datetimefrom peewee import *
import logging#查看peewee的日志信息
logger = logging.getLogger("peewee")
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())db = MySQLDatabase('peewee', host='127.0.0.1', user='root', passwd='******')class User(Model):#如果没有设置主键,那么自动生成一个id的主键username = CharField(primary_key=True, max_length=20)age = CharField(default=18, max_length=20, verbose_name="年龄")#migrations,class Meta: #大写database = dbclass Tweet(Model):#backref反向查询 外键设置了一对多的关系 #比如一个用户可以有多个Tweet  我拿到用户怎么查所有的Tweet 这时候backref就起作用了#我直接User.tweets就查到了user = ForeignKeyField(User, backref='tweets')message = TextField()#当前时间  注意不要用now()不要实现它created_date = DateTimeField(default=datetime.datetime.now)is_published = BooleanField(default=True)class Meta:#指明databasedatabase = db

防止连接丢失

如果是在项目中,可能会因为一个语句报错而丢失连接 而导致项目崩溃

from playhouse.shortcuts import ReconnectMixin
from playhouse.pool import PooledMySQLDatabase#实现这个类可以避免崩溃
class ReconnectMySQLDatabase(ReconnectMixin, PooledMySQLDatabase):passdb = ReconnectMySQLDatabase("mxshop_goods_srv", host="localhost", port=3306, user="root", password="123456")

二、表的设计&操作

0.继承

在设计表的时候可以设计一个BaseModel来继承它

class BaseModel(Model):add_time = DateTimeField(default=datetime.datetime.now, verbose_name="添加时间")class Meta:database = db  # 这里是数据库链接,为了方便建立多个表,可以把这个部分提炼出来形成一个新的类class Person(BaseModel):first = CharField()

1.添加

生成表

if __name__ == "__main__":#1. 生成表结构db.connect()#这个方法只能建表不能改表结构db.create_tables([User, Tweet])

原生SQL

    query = User.raw('SELECT * FROM new_user WHERE username = %s', "bobby5")query = User.select().where(SQL('username = "%s"' % "bobby5"))for q in query:print(q.username, q.age)

添加

if __name__ == "__main__":# 添加huey = User.create(username="huey")charlie = User(username="charlie") #update set age=18 where username="charlie"rows = charlie.save() #1. save方法既可以完成新建,也可以完成更新的操作(你的对象中主键值是否有设置,你是一个更新的操作)if rows == 0:print("未更新数据")Person.insert({'first': 'li3','last': 'bobby3'}).execute()

2.查询

    #3. 查询#1. get方法 - 1. 返回来的是直接的user对象 2. 这个方法如果查询不到会抛出异常try:# charlie = User.get(User.username=="charie")charlie = User.get_by_id("charie")print(charlie.username)#这个操作发起的sql请求是什么except User.DoesNotExist as e:print("查询不到")#2. 查询所有users = User.select() #1. 没有看到sql查询语句,用于组装sql 2. 对象是ModelSelect 我们对ModelSelect进行for循环和切片的时候才会发起请求# print(users.sql())print(type(users))# user = users[0] users[1:2]print(type(user))usernames = ["charlie", "huey", "mickey"]users = User.select().where(User.username.in_(usernames))for user in users:print(user.username)for user in User.select():print(user.username)

3.更新

charlie = User(username="charlie") #update set xx=xx where username="charlie"print(charlie.save())# 使用update更新print(User.update(age=20).where(User.username=="charlie").execute())

4.删除

	user = User.get(User.username=="huey")user.delete_instance()#是不是也不会执行# query = User.delete().where(User.username=="charlie").execute()# print(query)#有少数的方法会直接执行sql语句 get get_by_id

5.约束

class Person(BaseModel):first = CharField()last = CharField()class Meta:primary_key = CompositeKey('first', 'last')class Pet(BaseModel):owner_first = CharField()owner_last = CharField()pet_name = CharField()class Meta:constraints = [SQL('FOREIGN KEY(owner_first, owner_last) REFERENCES person(first, last)')]

6.复合主键

class Blog(BaseModel):passclass Tag(BaseModel):passclass BlogToTag(BaseModel):"""A simple "through" table for many-to-many relationship."""blog = ForeignKeyField(Blog)tag = ForeignKeyField(Tag)class Meta:primary_key = CompositeKey('blog', 'tag')

三、详细操作

1.like&排序&dict

    #likequery = Person.select().where(Person.first.startswith('bo'))#排序users = User.select().order_by(-User.age) #兼容了djangofor user in users:print(user.username, user.age)person = Person.select().order_by(Person.id.desc())for row in person:print(row)# 以字典形式输出query = Person.select().dicts()for row in query:print(type(row))print(row)

2.去重&统计

#distinct去重, count方法统计数量query = User.select(User.username).distinct().count()print(query)for q in query:print(q.username)print(query)# select user.name from user where age=(select max(age) from user)"""何时使用one():如果您有一个应该返回 1 个结果的查询,否则会引发异常——即使它返回 0 个结果。换句话说,它不允许 empty results.何时使用 scalar():如果您有一个返回 1 个结果或没有结果的查询。否则抛出异常。换句话说,它确实允许 empty results."""max_age = User.select(fn.MAX(User.age)).scalar()users = User.select().where(User.age==max_age)for user in users:print(user.username)sub_query = User.select(fn.MAX(User.age))query = User.select(User.username).where(User.age==sub_query)for q in query:print(q.username)query = User.raw('SELECT * FROM new_user WHERE username = %s', "bobby5")query = User.select().where(SQL('username = "%s"' % "bobby5"))for q in query:print(q.username, q.age)

四、避免n+1查询

# 使用表连接 能减少网络传输# query = Tweet.select(Tweet, User.username).join(User).where(User.username=="mickey")# for q in query:#     print(q.user.username, q.content)# query = Tweet.select(Tweet, User.username).join(User, on=(Tweet.user==User.id)).where(User.username=="mickey")# for q in query:#     print(q.user.username, q.content)#反向# user = User.get(User.username=="mickey")# tweets = Tweet.select().where(Tweet.user==user)# for tweet in tweets:#     print(user.username, tweet.content)#反向2# tweets = User.get(User.username == "mickey").tweets# # tweets = Tweet.select().where(Tweet.user == user)# for tweet in tweets:#     print(tweet.content)#想得到5个数据, 会发起5次请求 + 1 -> n+1查询# for tweet in Tweet.select():#     print(tweet.content, tweet.user.username)#什么时候sql会发起请求,以及会发起多少次请求, 开发人员来说 很重要 很多sql高手不会喜欢用ormquery = Tweet.select(Tweet, User.username).join(User).where(User.username == "mickey")for q in query:print(q.user.username, q.content)

http://chatgpt.dhexx.cn/article/FYw1dUAh.shtml

相关文章

Java之手写实现ORM框架

借鉴Mybatis框架手写一个ORM框架。mybatis整体架构中的整体思路是&#xff0c;首先解析一下配置文件&#xff0c;一个是框架的全局配置文件&#xff0c;一个是mapper配置文件&#xff0c;定义格式如下 <configuration> </configuration><mapper> </mappe…

ORM框架设计及实现

文章目录 一 对象记录映射二 效率和性能三 数据访问描述信息四 字段类型转换五 数据访问基类六 统一异常处理七 数据访问框架八 数据源创建工厂九 SQL指令解析十 补充DAO接口实现十一 测试十二 其他问题 一 对象记录映射 本质上来说&#xff0c;ORM框架需要处理的就是如何将JAV…

SpringBoot 构建ORM框架

目前常用的ORM框架有 Mybatis&#xff08;batis&#xff09;、MybatisPlus&#xff0c;Hibernate、Jpa等几个框架&#xff0c;今天就简单介绍一下搭建Mybatisplus框架的流程。 1.增加依赖 <dependencies><!-- 第一步&#xff1a;选择ORM框架&#xff0c;使用…

DjangoORM框架

DjangoORM框架 文章目录 DjangoORM框架一、ORM框架1.ORM简介2.使用django进行数据库开发的步骤如下&#xff1a;3.定义模型类4.迁移5.数据操作5.对象的关联操作6.ORM框架的功能 二、后台管理1.简介2.使用步骤3.管理界面本地化4.创建管理员5.注册模型类6.自定义管理页面 模型设计…

mybatis —— ORM框架

一、什么是框架 框架是一种经过校验、具有一定功能的半成品软件品&#xff0c;已经对基础的代码进行了封装并提供相应的API&#xff0c;开发者在使用框架是直接调用封装好的api可以省去很多代码编写&#xff0c;从而提高工作效率和开发速度。 二、什么是ORM ORM&#…

ORM框架——SqlSugar

目录 一、ORM框架 二、SqlSugar现状 三、SqlSugar的优点 四、SqlSugar的使用 五、主要函数 六、传参 五、读写分离 一、ORM框架 常用的ORM框架有Dapper、EF/EF Core、FreeSql、Dos.ORM、SqlSugar等&#xff0c;SqlSugar是国产的 二、SqlSugar现状 SqlSugar ORM 5.X 官…

很多小伙伴不太了解ORM框架的底层原理,这不,冰河带你10分钟手撸一个极简版ORM框架(赶快收藏吧)

大家好&#xff0c;我是冰河~~ 最近很多小伙伴对ORM框架的实现很感兴趣&#xff0c;不少读者在冰河的微信上问&#xff1a;冰河&#xff0c;你知道ORM框架是如何实现的吗&#xff1f;比如像MyBatis和Hibernate这种ORM框架&#xff0c;它们是如何实现的呢&#xff1f; 为了能够…

.Net Core ORM 框架

我的.net core orm 框架 一个简单的orm框架支持的数据库版本新的版本项目地址使用方式实现方式高级特性扩展函数性能bug 一个简单的orm框架 作者在使用很多orm框架的时候觉得查询语句写法似乎不是很好用&#xff0c;例如sqlSugar,EF,sqlSugar呢链接的时候必须注意表的别称&…

SQLAlchemy ORM框架

ORM简介 ORM 全称 Object Relational Mapping, 叫对象关系映射。简单的说&#xff0c;ORM 将数据库中的表与面向对象语言中的类建立了一种对应关系。这样&#xff0c;我们要操作数据库&#xff0c;数据库中的表或者表中的一条记录就可以直接通过操作类或者类实例来完成。 对于…

ORM框架

ORM框架 一、什么是ORM框架 对象关系映射&#xff08;Object Relational Mapping&#xff0c;简称ORM&#xff09;模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术 ORM框架是连接数据库的桥梁&#xff0c;只要提供了持久化类与表的映射关系&#xff0c;OR…

ORM框架使用优缺点

1. 什么是ORM? 对象-关系映射&#xff08;Object-Relational Mapping&#xff0c;简称ORM&#xff09;&#xff0c;面向对象的开发方法是当今企业级应用开发环境中的主流开发方法&#xff0c;关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业…

Redis I/O 多路复用

引出IO多路复用 为什么 Redis 中要使用 I/O 多路复用这种技术呢&#xff1f; 首先&#xff0c;Redis 是跑在单线程中的&#xff0c;所有的操作都是按照顺序线性执行的&#xff0c;但是由于读写操作等待用户输入或输出都是阻塞的&#xff0c;所以 I/O 操作在一般情况下往往不能…

IO多路复用—由Redis的IO多路复用yinch

linux IO多路复用有epoll&#xff0c; poll, select&#xff0c;epoll性能比其他几者要好。 名词比较绕口&#xff0c;理解涵义就好。一个epoll场景&#xff1a;一个酒吧服务员&#xff08;一个线程&#xff09;&#xff0c;前面趴了一群醉汉&#xff0c;突然一个吼一声“倒酒”…

什么是IO多路复用?用来解决什么问题?如何实现?

白话IO多路复用 这里引述知乎大佬对于IO多路复用的机场空管的比喻和理解&#xff1a; 假设你是一个机场的空管&#xff0c; 你需要管理到你机场的所有的航线&#xff0c; 包括进港&#xff0c;出港&#xff0c; 有些航班需要放到停机坪等待&#xff0c;有些航班需要去登机口接…

I/O多路复用

https://blog.csdn.net/baixiaoshi/article/details/48708347 https://blog.csdn.net/z69183787/article/details/52943917 select&#xff0c;poll&#xff0c;epoll都是IO多路复用的机制。所谓I/O多路复用机制&#xff0c;就是说通过一种机制&#xff0c;可以监视多个描述符…

概念 多路复用 到底是个啥?通俗易懂的理解

前言&#xff1a;教育的公平才是最大的公平&#xff0c;本科和专科还是有点差别的。时间长点学方面会充实些。 先给个结论&#xff1a;I/O多路复用技术&#xff08;就是大家经常说的事件循环&#xff09;实际上&#xff0c;事件驱动模型还有另外一个名字&#xff0c;而且更加出…

Redis的IO多路复用原理

什么是阻塞&#xff0c;非阻塞&#xff0c;异步同步&#xff0c;select&#xff0c;poll&#xff0c;epoll&#xff1f;今天我们用一遍文章解开这多年的迷惑。 首先我们想要通过网络接收消息&#xff0c;是这样的一个步骤。 用户空间向内核空间请求网络数据内核空间把网卡数据…

什么是IO多路复用,理解IO多路复用

什么是IO多路复用&#xff1f; IO 多路复用是一种同步IO模型&#xff0c;实现一个线程可以监视多个文件句柄&#xff1b;一旦某个文件句柄就绪&#xff0c;就能够通知应用程序进行相应的读写操作&#xff1b;没有文件句柄就绪就会阻塞应用程序&#xff0c;交出CPU。 多路是指网…

多路复用与多路分用

从现在开始&#xff0c;我们开始传输层的学习&#xff0c;自顶向下第六版中改成了运输层&#xff0c;感觉怪怪的 书中打了邮政服务和代收发信件的兄弟姐妹之间的比方&#xff0c;非常贴切&#xff0c;这是传输层和网络层的作用区别&#xff0c;也就是说&#xff0c;传输层管的是…

多路复用(

apue 多路复用 需求来自用户&#xff0c;用户的需求来自实际的使用场景。在实际运用中&#xff0c;一个系统或者程序需要处理的事件并不是只有一个或一类&#xff0c;而是存在各种各样的事件在一小段事件内一起发生&#xff0c;此时按照没学多线程的逻辑的处理方式就是这样&…