peewee是一款orm框架,为什么选择peewee,是因为它比较简单和Django比较类似,而且还有一个async-peewee,可以进行异步化。

如何定义model和生成表

'''
我们要定义两张表,一张商品,一张商品供应商。商品表里面有一个外键对应商品供应商
'''
import peewee # 第一个参数是我们数据库的名字,其他的参数则跟pymysql一样
db = peewee.MySQLDatabase("satori", host="localhost", port=3306, user="root", password="zgghyys123") # 定义供应商
class Supplier(peewee.Model):
# max_length:最大长度。verbose_name:注释信息。index:是否设置为索引
name = peewee.CharField(max_length=100, verbose_name="供应商名称", index=True)
address = peewee.CharField(max_length=200, verbose_name="供应商地址")
phone = peewee.CharField(max_length=11, verbose_name="联系电话") class Meta:
# 和Django比较类似,绑定一个数据库实例
database = db
# 设置表名
table_name = "supplier" class Goods(peewee.Model):
# 我们这里没有指定主键,那么会默认创建一个id列作为主键,如果SQLAlchemy的话必须要自己指定
name = peewee.CharField(max_length=100, verbose_name="商品名称", index=True)
click_num = peewee.IntegerField(default=0, verbose_name="点击数")
goods_num = peewee.IntegerField(default=0, verbose_name="库存")
price = peewee.FloatField(default=0.0, verbose_name="价格")
brief = peewee.TextField(verbose_name="商品简介")
# 绑定外键,和Django一样
# backref:反向引用。既然定义了外键,我们可以在Goods可以通过supplier访问到Supplier。
# 那么如何通过Supplier访问到Goods呢?那么就可以通过backref指定的goods来访问。这个SQLAlchemy也是一样的
# 但SQLAlchemy中,我们不仅要自己指定外键,并且定义反向引用的时候还要导入一个relationship supplier = peewee.ForeignKeyField(Supplier, verbose_name="供应商", backref="goods") class Meta:
database = db
table_name = "goods" if __name__ == '__main__':
# 以上表便定义完成了,下面映射到数据库
# 直接使用db.create_tables即可,将要映射成表的模型放在列表里传进去
db.create_tables([Goods, Supplier])

model的数据保存

# 导入模型
from model import Goods, Supplier supplier_list = [
{
"name": "淘宝",
"address": "杭州",
"phone": "15548452158"
},
{
"name": "天猫",
"address": "杭州",
"phone": "15422584552"
},
{
"name": "京东",
"address": "北京",
"phone": "15424896324"
},
{
"name": "蘑菇街",
"address": "上海",
"phone": "15545221485"
}
] goods_list = [
{
"name": "护舒宝",
"click_num": 100,
"goods_num": 666,
"price": 10,
"brief": "防侧漏",
"supplier": 1,
},
{
"name": "苏菲",
"click_num": 120,
"goods_num": 874,
"price": 8,
"brief": "双面侧翼,安心无忧",
"supplier": 2,
},
{
"name": "毓婷",
"click_num": 60,
"goods_num": 541,
"price": 30,
"brief": "有毓婷,放心爱",
"supplier": 3 },
{
"name": "冈本001",
"click_num": 5800,
"goods_num": 1500,
"price": 60,
"brief": "冈本超薄,给您最极致的体验",
"supplier": 4 }
] def save_model():
# 添加单个元素直接这样添加即可, 然后使用save保存
'''
supplier = Supplier()
supplier.name = "淘宝"
supplier.address = "杭州"
supplier.phone = "15841259841" supplier.save()
''' # 添加多个元素的话
for data in supplier_list:
supplier = Supplier()
supplier.name = data["name"]
supplier.address = data["address"]
supplier.phone = data["phone"] supplier.save() for data in goods_list:
'''
也可以这样添加
goods = Goods(name=data["name"], click_num=data["click_num"], goods_num=data["goods_num"], price=data["price"], brief=data"brief"])
'''
# data里的key要和Goods模型定义的列名保持一致
goods = Goods(**data)
goods.save() if __name__ == '__main__':
save_model()

peewee查询数据

from model import Goods
import peewee # 获取某条数据,可以通过get方式查询,模型里面虽然没有定义id,但是表里面有,这个查找会映射到表里面去查找
good1 = Goods.get(Goods.id == 1)
# 虽然显示的是1,因为我们是按照id查找的,所以默认显示id
print(good1) # 1
# 但其实是一个<Model: Goods>
print(type(good1)) # <Model: Goods>
# 可以用这个good1查找其它属性
print(good1.name, " T_T ", good1.brief) # 护舒宝 T_T 防侧漏 # 同理也可以根据其它字段查询
good2 = Goods.get(Goods.name == "冈本001")
print(good2.brief) # 冈本超薄,给您最极致的体验 # 如果是通过id获取的话,那么有两个专门的方式
good3 = Goods.get_by_id(2)
print(good3) # 2
print(good3.name, " --- ", good3.brief) # 苏菲 --- 双面侧翼,安心无忧
# 还可以像列表一样传值,但是里面的值并不是索引,而是id
good4 = Goods[3]
print(good4, type(good4)) # 3 <Model: Goods>
print(good4.name, " --- ", good4.brief) # 毓婷 --- 有毓婷,放心爱
'''
为什么可以使用Goods[3]这种方式,看一下源码,会发现peewee.Model继承的父类有这么一段
def __getitem__(self, key):
return self.get_by_id(key)
实际上是实现了__getitem__这个魔法方法,而底层还是使用了get_by_id
''' # 获取所有数据
'''
这句话等价于select * from goods,但是这是一个懒执行,类似于spark里面的transform,或者python里面的迭代器
像get,get_by_id等方法,使用之后会立即组成sql语句然后去查询,但是select返回的是<class 'peewee.ModelSelect'>这个类
会组成sql语句,但不会立即执行,而是当我们使用for循环迭代的时候,才会执行.
如何实现,实际上是底层实现了迭代协议
'''
good5 = Goods.select()
for good in good5:
# 即便在循环的时候,打印good默认还是打印id
print(good, type(good), good.name, good.click_num, good.brief)
'''
1 <Model: Goods> 护舒宝 100 防侧漏
2 <Model: Goods> 苏菲 120 双面侧翼,安心无忧
3 <Model: Goods> 毓婷 60 有毓婷,放心爱
4 <Model: Goods> 冈本001 5800 冈本超薄,给您最极致的体验
'''
# 此外如果我们想看执行的sql语句,可以使用good5.sql()进行查看
print(good5.sql()) # ('SELECT `t1`.`id`, `t1`.`name`, `t1`.`click_num`, `t1`.`goods_num`, `t1`.`price`, `t1`.`brief`, `t1`.`supplier_id` FROM `goods` AS `t1`', [])
# 关于select,如果我们不想选择所有的字段呢?那么可以传入想获取的字段名
good6 = Goods.select(Goods.name, Goods.price)
for good in good6:
# good虽然是<Model: Goods>,但是打印good默认还是打印id,但是我们查询的没有id只有name和price。
# 因此good为None,good.brief也为None
print(good, good.name, good.price, good.brief)
'''
None 护舒宝 10.0 None
None 苏菲 8.0 None
None 毓婷 30.0 None
None 冈本001 60.0 None
''' # 根据条件获取
# select * from goods where price > 8.0
good7 = Goods.select().where(Goods.price > 8.0)
for good in good7:
print(good.name)
'''
护舒宝
毓婷
冈本001
'''
# select * from goods where price > 8.0 and price < 60.0 ,同理or的话就用|
good8 = Goods.select().where((Goods.price > 8.0) & (Goods.price < 60.0))
for good in good8:
print(good.name)
'''
护舒宝
毓婷
'''
# select * from goods where name is like "%宝"
good9 = Goods.select().where(Goods.name.contains("宝"))
'''
也可以这么写
good9 = Goods.select().where(Goods.name % "%宝")
'''
for good in good9:
print(good.name)
'''
护舒宝
'''
# 同理Goods.name.startswith和Goods.name.endswith也是支持的
# select * from goods where id in (1, 3)
good10 = Goods.select().where(Goods.id.in_([1, 3])) # 这里可以用in_,也可以用<<
'''
good10 = Goods.select().where(Goods.id << [1, 3])
'''
for good in good10:
print(good.name, good)
'''
护舒宝 1
毓婷 3
'''
# select * from goods where id between 1 and 3
good11 = Goods.select().where(Goods.id.between(1, 3))
for good in good11:
print(good.name, good.id)
'''
护舒宝 1
苏菲 2
毓婷 3
''' # 还可以使用正则,注意这里的正则是mysql里面的正则,不是python里面的正则
'''
^a:以a开头的字符
a$:以a结尾的字符
.:匹配除了\n之外的任意字符
[....]:匹配包含在[....]里面的字符
[^....]:匹配不包含在[....]里面的字符
a|b|c:匹配a或b或c
*:重复零次或多次
?:重复零次或一次
+:重复一次或多次
需要注意:
1.like和regexp不要混用,like模式不支持正则,正则也不认识_,%
2.mysql里的正则没有贪婪非、贪婪匹配啥的
3.这里是mysql的正则,不是python的正则,所以不要出现\d,\w之类的
'''
good12 = Goods.select().where(Goods.name.regexp(r"宝$"))
for good in good12:
print(good, good.name)
'''
1 护舒宝
'''
# 忽略大小写,由于是中文,因此结果是一样的
good13 = Goods.select().where(Goods.name.iregexp(r"宝$"))
for good in good13:
print(good, good.name)
'''
1 护舒宝
''' # 选出click_num大于goods_num的
good14 = Goods.select().where(Goods.click_num > Goods.goods_num)
for good in good14:
print(good.click_num, good.goods_num, good.name)
'''
5800 1500 冈本001
''' # 选出click_num小于goods_num的
good14 = Goods.select().where(Goods.click_num < Goods.goods_num)
for good in good14:
print(good.click_num, good.goods_num, good.name)
'''
100 666 护舒宝
120 874 苏菲
60 541 毓婷
''' # 排序
# select * from goods order by click_num desc
good15 = Goods.select().order_by(Goods.click_num.desc()) # 同理还有升序asc, 如果是输入字段名那么默认升序
for good in good15:
print(good.name, good.click_num)
'''
冈本001 5800
苏菲 120
护舒宝 100
毓婷 60
'''
# 这个orm是仿照Django的,而且Django支持使用+表示升序,-表示降序
good16 = Goods.select().order_by(+Goods.click_num)
for good in good16:
print(good.click_num, good.name)
'''
60 毓婷
100 护舒宝
120 苏菲
5800 冈本001
'''
good17 = Goods.select().order_by(-Goods.click_num)
for good in good17:
print(good.click_num, good.name)
'''
5800 冈本001
120 苏菲
100 护舒宝
60 毓婷
''' # 使用count查询表中共有多少条数据
good18 = Goods.select().count()
print(good18) # 分组,聚合
'''
from peewee import fn
fn.COUNT
fn.SUM
''' # 分页
# 表示从第二行开始取两行数据,索引是从零开始的
good19 = Goods.select().group_by(Goods.price).paginate(1, 2)
for good in good19:
print(good.name, good.price)
'''
苏菲 8.0
护舒宝 10.0
'''

peewee更新数据和删除数据

from model import Goods

good1 = Goods.get_by_id(1)
print(good1.name, good1.price) # 护舒宝 10.0
# 获取id=1的记录,就像添加数据一样进行修改.
good1.price = 11.0
good1.save()
print(good1.name, good1.price) # 护舒宝 11.0 # 数据修改还可以使用update
good2 = Goods.get_by_id(4)
print(good2.name) # 冈本001
# 注意:update里面不需要模型了,直接输入字段名就可以了,因为在where中已经知道表名了
# 必须要execute才会生效
Goods.update(name="冈本002").where(Goods.id == 4).execute()
print(Goods.get_by_id(4).name) # 冈本002
# 但是
print(Goods.get_by_id(4).price) # 60.0
# 如果是这样更新的话, 右边必须加上模型名,否则报错
Goods.update(price=Goods.price+10).where(Goods.id == 4).execute()
print(Goods.get_by_id(4).price) # 70.0 # 删除一条记录
good3 = Goods.get_by_id(2)
# 这样获取到的id=2的记录便被删除了
good3.delete_instance()
try: # select方法,如果没数据,那么为空,但是get或者get_by_id如果获取不到数据会抛异常,GOODS.DoseNotExist
Goods.get_by_id(2)
except Exception:
import traceback
print(traceback.format_exc())
'''
Traceback (most recent call last):
File "D:/龙卷风/chapter1/update_delete_data.py", line 29, in <module>
Goods.get_by_id(2)
File "C:\python37\lib\site-packages\peewee.py", line 5629, in get_by_id
return cls.get(cls._meta.primary_key == pk)
File "C:\python37\lib\site-packages\peewee.py", line 5618, in get
return sq.get()
File "C:\python37\lib\site-packages\peewee.py", line 6021, in get
(clone.model, sql, params))
model.GoodsDoesNotExist: <Model: Goods> instance matching query does not exist:
SQL: SELECT `t1`.`id`, `t1`.`name`, `t1`.`click_num`, `t1`.`goods_num`, `t1`.`price`, `t1`.`brief`, `t1`.`supplier_id` FROM `goods` AS `t1` WHERE (`t1`.`id` = %s) LIMIT %s OFFSET %s
Params: [2, 1, 0]
'''
# delete from goods where price > 0.0
# 这个同样需要execute,否则是不会执行的,这下估计会把数据全部清空
Goods.delete().where(Goods.price > 0.0).execute()

orm之peewee的更多相关文章

  1. 3.orm之peewee

    peewee是一款orm框架,为什么选择peewee,是因为它比较简单和Django比较类似,而且还有一个async-peewee,可以进行异步化. 如何定义model和生成表 ''' 我们要定义两张 ...

  2. python轻量级orm框架 peewee常用功能速查

    peewee常用功能速查 peewee 简介 Peewee是一种简单而小的ORM.它有很少的(但富有表现力的)概念,使它易于学习和直观的使用. 常见orm数据库框架 Django ORM peewee ...

  3. Python:轻量级 ORM 框架 peewee 用法详解(二)——增删改查

    说明:peewee 中有很多方法是延时执行的,需要调用 execute() 方法使其执行.下文中不再特意说明这个问题,大家看代码. 本文中代码样例所使用的 Person 模型如下: class Per ...

  4. Python初学者之网络爬虫(二)

    声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...

  5. Python框架、库以及软件资源汇总

    转自:http://developer.51cto.com/art/201507/483510.htm 很多来自世界各地的程序员不求回报的写代码为别人造轮子.贡献代码.开发框架.开放源代码使得分散在世 ...

  6. [转载] ORMs under the hood

    原文: http://www.vertabelo.com/blog/technical-articles/orms-under-the-hood It often happens that if so ...

  7. python模块 - 常用模块推荐

    http://blog.csdn.net/pipisorry/article/details/47185795 python常用模块 压缩字符 当谈起压缩时我们通常想到文件,比如ZIP结构.在Pyth ...

  8. python 基础部分重点复习整理2

    把这里的题目争取刷一遍 博客记录 python的ORM框架peewee SQLAlchemy psycopg2 Django 在1 的基础上,重点突出自己以前没注意的,做到精而不杂!!! Python ...

  9. python web需要了解哪些

    1. socket.tcp/ip.http(cookie.session.token).https.ssl 2. wsgi:https://www.python.org/dev/peps/pep-33 ...

随机推荐

  1. 如何选择K-Means中K的值

    K-Means需要设定一个簇心个数的参数,现实中,最常用于确定K数的方法, 其实还是人手工设定.例如,当我们决定将衣服做成几个码的时候,其实就是在以 人的衣服的长和宽为为特征进行聚类.所以,弄清楚我们 ...

  2. Java界面程序实现图片的放大缩小

    Java界面程序实现图片的放大缩小.这个程序简单地实现了图片的打开.保存.放大一倍.缩小一倍和固定缩放尺寸,但是并没有过多的涵盖对图片的细节处理,只是简单地实现了图片大小的放缩. 思维导图如下: 效果 ...

  3. CallableStatement获得存储过程多个结果集

    这里使用到的数据库为MySQL package com.dz.entity; import java.sql.*; public class Pro_inoutTest { public static ...

  4. koa cookie使用

    1 .Koa 中设置 Cookie 的值 ctx.cookies.set(name, value, [options])  通过 options 置 设置 cookie name 的 value : ...

  5. 自动创建数据库(DELPHI+SQL SERVER)

    procedure TForm1.Btn_OKClick(Sender: TObject); var sqlconn:string; begin Sqlconn:='Provider=SQLOLEDB ...

  6. CentOS的SVN服务器搭建与自动部署全过程

    CentOS的SVN服务器搭建与自动部署全过程 http://www.jb51.net/article/106218.htm authz-db = authz 引起的 svn 认证失败 http:// ...

  7. redis外网无法连接问题

    1.外网无法连接redis 解决方法: 把redis.conf里的bind 127.0.0.1注释掉,不行的话把127.0.0.1修改成0.0.0.0 2.make的时候显示没有gcc 解决方法: 安 ...

  8. DESC加密解密算法

    using System; using System.Text; using System.Windows.Forms; using System.Security.Cryptography; usi ...

  9. 外连接的用法 -- 《SQL进阶教程》 jupyter note

    import pandas as pd import sqlite3 conn = sqlite3.connect('1-5.db') 用外连接进行行列转换1(行 -> 列): 制作交叉表 怎么 ...

  10. linux下使用URLOS搭建nextcloud私有云盘系统

    Nextcloud是一个免费专业的私有云存储网盘开源项目,可以让你简单快速地在个人/公司电脑.服务器甚至是树莓派等设备上架设一套属于自己或团队专属的云同步网盘,从而实现跨平台跨设备文件同步.共享.版本 ...