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

  

peewee-async

首先还是要pip install --pre peewee-async,为什么要加上--pre,因为目前不支持python3.7,如果是python3.6的话直接安装即可

3.orm之peewee的更多相关文章

  1. 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. EM算法浅析(二)-算法初探

    EM算法浅析,我准备写一个系列的文章: EM算法浅析(一)-问题引出 EM算法浅析(二)-算法初探 一.EM算法简介 在EM算法之一--问题引出中我们介绍了硬币的问题,给出了模型的目标函数,提到了这种 ...

  2. JSONP跨域jQuery处理整理(附天气数据实例)

    写在前面 跨域的解决方案有多种,其中最常见的是使用同一服务器下的代理来获取远端数据,再通过ajax进行读取,而在这期间经过了两次请求过程,使得获取数据的效率大大降低,这篇文章蓝飞就为大家介绍一下解决跨 ...

  3. linux下easy_install的安装与使用详解

    Python中的easy_install工具用起来非常好用,它的作用类似于Php中的pear,或者Ruby中的gem,或者Perl中的cpan. 1.easy_install安装 如果想使用easy_ ...

  4. 使用window.getSelection()获取div中选中文字内容及位置

    div添加一个弹出事件: $(document).ready(function () { $("#marked-area").mouseup(function (e) { $sco ...

  5. 获取Parameter参数值,方便调试使用

    #region #warning 调试使用,获取sql参数化,拼接出完整的sql语句,复制sql明文到mssql中运行 string debugSql = queryHelper.CommandTex ...

  6. taotao购物车

    功能分析: 1.在用户不登陆的情况下也可以使用购物车,那么就需要把购物车信息放入cookie中. 2.可以把商品信息,存放到pojo中,然后序列化成json存入cookie中. 3.取商品信息可以从c ...

  7. Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) B

    B. Problems for Round time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  8. [洛谷P2073] 送花

    送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地 ...

  9. [fzu 2273]判断两个三角形的位置关系

    首先判断是否相交,就是枚举3*3对边的相交关系. 如果不相交,判断包含还是相离,就是判断点在三角形内还是三角形外.两边各判断一次. //http://acm.fzu.edu.cn/problem.ph ...

  10. tomcat 配置文件中设置JAVA_HOME

    Tomcat默认情况下会用系统的环境变量中找到JAVA_HOME和JRE_HOME.但是有的时候我们需要不同版本的JDK共存. 可以在${TOMCAT_HOME}/bin/setclasspath.b ...