前期准备
• 安装peewee,
• pip3 install peewee
• 在学习peewee之前先了解下ORM(Object Relational Mapping)对象关系映射,解决面向对象与关系数据库不匹配的技术。
• peewee是一种轻量级的python ORM
• 可以理解为MongoDB与NoSQL的关系
• 在学习peewee时,发现其中大量使用了内部类,就重新补充了一下关于内部类的知识点
• 关于使用内部类的优势
• 内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围类对象那个的信息相互独立;
• 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类;
• 创建内部类对象的时刻并不依赖于外围类对象的创建;
• 内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体。
• 安装mysql
• 从官网安装最新版本
• 注意的是安装完成后需要修改密码才能进行外部连接
• Peewee中数据类型对照表
Db.is_closed()#判断数据库是不是连接
Db.connect()#连接数据库
Db.create_tables([Person,])#建表
或者Person.create_tables();#Person是一个类名
关于主键和约束 #都是在类的内部类中定义
class Person(Model):
first = CharField()
last = CharField()
class Meta:
primary_key = CompositeKey('first', 'last')
class Pet(Model):
owner_first = CharField()
owner_last = CharField()
pet_name = CharField()
class Meta:
constraints = [SQL('FOREIGN KEY(owner_first, owner_last) '
'REFERENCES person(first, last)')]
插入数据P=Person.create(name=’name’,sex=’sex’);
p.save();
或者使用
Person.insert(name=’name’,sex=’sex’).execute();
关于从一个表查数据快速插到另一个表 还需再思考下
修改数据
Tweet.update(message='这是修改过的数据').where(Tweet.id==3).execute();
注意的是,在peewee中条件中使用‘==’。更新的数据不用加类名,但是条件中的字段必须加类名。
数据删除
Tweet.update(message='这是修改过的数据3').where(Tweet.id==3).execute();
数据查询
User.get(id=1);#一条
User.get_by_id(1);
ts=Tweet.filter(user_id=1);#所有迭代器
注意:使用get()并且没有参数返回的是查询的id
复合查询
q=User.select().where((User.id==1)|(User.username=='tom')).get();
q=User.select().where((User.id==1)&(User.username=='tom')).get();
模糊查询
#select * from Tweet where message like ’%数据%’;
print(Tweet.select().where(Tweet.message ** "%数据%").get());
print(Tweet.select().where(Tweet.message.contains('数据')).get());
in 查询
print(Tweet.select().where(Tweet.id.in_([1, 2])).get());
Order by; Limit; Distinct; Group by; Having
query = (Person.select(Person.name).order_by(Person.name).limit(10).distinct()) # 几乎和sql一模一样
Person.select().order_by(Person.birthday.desc()) # 日期排序
query = (Booking
.select(Booking.facid, fn.SUM(Booking.slots))
.group_by(Booking.facid) # group_by
.order_by(Booking.facid))
query = (Booking
.select(Booking.facility, fn.SUM(Booking.slots))
.group_by(Booking.facility)
.having(fn.SUM(Booking.slots) > 1000) # having
.order_by(Booking.facility))
Tweet.select().order_by(-Tweet.created_date)
# 返回查到了多少条记录
Tweet.select().where(Tweet.id > 50).count()
连表查询
g1 = Person.select().join(Pet).where(Pet.name == "dog2")
实例讲解
参考(https://www.cnblogs.com/fnng/p/6879779.html)
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
from peewee import *;
import datetime;
#建立连接mysql时的必要参数
db = MySQLDatabase('peewee_learn',host ='127.0.0.1',user='root',passwd='123456');
#连接数据库
db.connect();
class BaseModel(Model):
#内部类
class Meta:
database=db;#每一个继承BaseModel类的子类都是连接db表
class User(BaseModel):
username=CharField(unique=True);#每个属性都是一个表字段
class Tweet(BaseModel):
user = ForeignKeyField(User,related_name='tweets');
message = TextField();
created_date = DateTimeField(default=datetime.datetime.now);
is_published = BooleanField(default=True);
if __name__ == '__main__':
#创建表
User.create_table();#创建User表
Tweet.create_table();#创建Tweet表
#插入数据
#user=User.create(username='tom');
#Tweet.create(user=user,message='这是一段文字');
#Tweet.create(user_id=1,message='这是第二段文字');
#查询数据get()
#t = Tweet.get(message="这是一段文字")
#print(t.user_id)
#print(t.created_date)
#print(t.is_published)
#filter
#ts=Tweet.filter(user_id=1);
#for t in ts:
#print(t.message);
首先,导入peewee库下面的所有方法,这个当然需要。
然后,通过MySQLDatabase连接数据库,把数据连接的几个必要参数一一填写。通过connect()方法与MySQL数据库建立链接。
接下来就是表的创建,创建BaseModel类,在该类下创建子类Meta,Meta是一个内部类,它用于定义peewee的Model类的行为特性。指定dabatase 为 前面定义的db。
再接下来就是表的创建了,我们在SQL语句创建表时一般需要知道以下信息。表的名字,表有哪些字段?这些字段分别是什么类型?是否允许为空,或自增?哪个字段是主键是?哪个是外键?
ORM用编程语言里的概念帮我们映射了这些东西。
创建 User 和 Tweet类做为表名。在类下面定义的变量为字段名,如username、message、created_date等。通过CharField、DateTimeField、BooleanField表示字段的类型。ForeignKeyField 建立外键。 主键呢? 建表时不都要有个主键id嘛,不用!peewee默认已经为我们加上这个id了。
最后,执行create_table()方法创建两张表。
通过数据库工具,查看生成的两张表。
插入数据
要想操作数据,首先表里需要有数据。先来看看如何添加数据。
if __name__ == "__main__":
# ...
user = User.create(username='tom')
Tweet.create(user=user, message="这是一段文字")
这样就要User表里添加一个tom的用户,这用户发了一条Tweet,在Tweet表里。但这个用户兴致来了,想继续发第二条Tweet。于是:
if __name__ == "__main__":
# ...
Tweet.create(user_id=1, message="这是第二段文字")
咦~!?不对,我们没有创建user_id字段啊!但是,如果你查询Tweet表,就会发现有这个字段,用它来关联User表的id
查询数据
if __name__ == "__main__":
# ...
# 查询 1
t = Tweet.get(message="这是一段文字")
print(t.user_id)
print(t.created_date)
print(t.is_published)
查询结果
1
2017-05-19 15:44:32
True
不过,get()方法只能查询一条,且是唯一的一条数据;通过查询条件不能查询出多条,也不能查询出0条。
if __name__ == "__main__":
# ...
# 查询 2
ts = Tweet.filter(user_id=1)
for t in ts:
print(t.message)
运行结果
这是一段文字
这是第二段文字
而,filter()方法,就会更加灵活,可以查询多条结果,并把结果循环输出。
删除数据
参考https://www.cnblogs.com/fnng/p/6879779.html
https://www.cnblogs.com/yxi-liu/p/8514763.html