美文网首页
python web开发之数据库ORM的 peewee库 动手学

python web开发之数据库ORM的 peewee库 动手学

作者: 小钟钟同学 | 来源:发表于2018-03-21 23:02 被阅读162次

    背景

    在web开发的时候,一些比较简单的小型系统其实也得ORM框架,显而易见其实开发速度上是提升很多,因为有必要学习一下对应的ORM库。

    关于ORM一些说明

    关于ORM(Object Relational Mapping,对象关系映射)在python中其实存在几个,主要有的还有SQLAlchemy,不过其实今天咋们的猪脚peewee的内核其实也是基于SQLAlchemy,所以可能应该是更加高效!因为还没做进行具体的测试和数据对比,所以现在还是猜测!
    后期我也会继续实践一下关于SQLAlchemy在bottle中的使用!

    理论上相关ORM应该具备的能力有:
    (1)对象关系映射(数据类型映射,类映射,关系映射)
    (2)CURD操作
    (3)缓存优化

    ORM一些优点:
    (1)屏蔽数据库操作细节,开发者不需要通过SQL进行和数据库进行交互,提高开发效率
    (2)便捷数据库迁移
    (3)缓存技术提高数据库操作效率。

    安装

    pip install peewee
    
    image.png

    示例

    因为我这边的环境数据库使用的还是Postgresql,所以示例我就以Postgresql为主:

    先通过navicat在本地新建一个测试数据库叫做:test_peewee


    image.png

    新建一个py文件(LearnPeewee.py):


    image.png

    #!/usr/bin/evn python
    # coding=utf-8
    # + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +
    #        ┏┓   ┏┓+ +
    #    ┏┛┻━━━┛┻┓ + +
    #    ┃       ┃  
    #    ┃   ━   ┃ ++ + + +
    #    ████━████ ┃+
    #    ┃       ┃ +
    #    ┃   ┻   ┃
    #    ┃       ┃ + +
    #    ┗━┓   ┏━┛
    #      ┃   ┃           
    #      ┃   ┃ + + + +
    #      ┃   ┃    Codes are far away from bugs with the animal protecting   
    #      ┃   ┃ +     神兽保佑,代码无bug  
    #      ┃   ┃
    #      ┃   ┃  +         
    #      ┃    ┗━━━┓ + +
    #      ┃        ┣┓
    #      ┃        ┏┛
    #      ┗┓┓┏━┳┓┏┛ + + + +
    #       ┃┫┫ ┃┫┫
    #       ┗┻┛ ┗┻┛+ + + +
    # + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +"""
    """
    Author = zyx
    @Create_Time: 2018/3/21 23:11
    @version: v1.0.0
    @Contact: 308711822@qq.com
    @File: LearnPeewee.py
    @文件功能描述:
    """
    from peewee import *
    
    # 建立一个PostgresqlDatabase数据库引擎对象,连接到本地的数据库
    db = PostgresqlDatabase("test_peewee", host="localhost", port=5432, user="postgres", passwd="123456")
    db.connect()
    
    # 定义一个ORM基类,在基类中指定本ORM所使用的数据库
    class BaseModel(Model):
        class Meta:
            database = db
    
    
    # 定义一个Course表(课程表)。继承于BaseModel
    class Course(BaseModel):
        id = PrimaryKeyField()  # 课程唯一标识
        title = CharField(null=False)  # 课程名称
        period = IntegerField()  # 学时
        des = CharField()  # 课程描述
    
        class Meta:
            order_by = {'title', }
            db_table = 'course'  # 定义数据库中表的名称
    
    
    # 定义一个Teacher表(老师表)。继承于BaseModel
    class Teacher(BaseModel):
        id = PrimaryKeyField()  # 唯一标识
        name = CharField(null=False)  # 名称
        gender = BooleanField()  # 性别
        address = CharField()  # address地址
        course_id = ForeignKeyField(Course, to_field='id', related_name='course')
    
        class Meta:
            order_by = {'name', }
            db_table = 'teacher'  # 定义数据库中表的名称
    
    
    # 执行建表,只需要执行一次
    Course.create_table()
    Teacher.create_table()
    

    执行报错:


    image.png

    原因是:

    连接字段参数错误
    passwd--->password
    
    
    # 建立一个PostgresqlDatabase数据库引擎对象,连接到本地的数据库
    db = PostgresqlDatabase("test_peewee", host="localhost", port=5432, user="postgres", password="123456")
    db.connect()
    

    执行成功后查看一下对应的数据库表的情况:

    image.png

    代码:

    #!/usr/bin/evn python
    # coding=utf-8
    # + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +
    #        ┏┓   ┏┓+ +
    #    ┏┛┻━━━┛┻┓ + +
    #    ┃       ┃  
    #    ┃   ━   ┃ ++ + + +
    #    ████━████ ┃+
    #    ┃       ┃ +
    #    ┃   ┻   ┃
    #    ┃       ┃ + +
    #    ┗━┓   ┏━┛
    #      ┃   ┃           
    #      ┃   ┃ + + + +
    #      ┃   ┃    Codes are far away from bugs with the animal protecting   
    #      ┃   ┃ +     神兽保佑,代码无bug  
    #      ┃   ┃
    #      ┃   ┃  +         
    #      ┃    ┗━━━┓ + +
    #      ┃        ┣┓
    #      ┃        ┏┛
    #      ┗┓┓┏━┳┓┏┛ + + + +
    #       ┃┫┫ ┃┫┫
    #       ┗┻┛ ┗┻┛+ + + +
    # + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +"""
    """
    Author = zyx
    @Create_Time: 2018/3/21 23:11
    @version: v1.0.0
    @Contact: 308711822@qq.com
    @File: LearnPeewee.py
    @文件功能描述:
    """
    from peewee import *
    from playhouse.shortcuts import model_to_dict, dict_to_model
    
    # from playhouse.pool import PooledPostgresqlExtDatabase
    #
    # db = PooledPostgresqlExtDatabase(
    #     'my_database',
    #     max_connections=8,
    #     stale_timeout=300,
    #     user='postgres')
    #
    # class BaseModel(Model):
    #     class Meta:
    #         database = db
    
    # 建立一个PostgresqlDatabase数据库引擎对象,连接到本地的数据库
    db = PostgresqlDatabase("test_peewee", host="localhost", port=5432, user="postgres", password="123456")
    db.connect()
    
    
    # 定义一个ORM基类,在基类中指定本ORM所使用的数据库
    class BaseModel(Model):
        class Meta:
            database = db
    
    
    # 定义一个Course表(课程表)。继承于BaseModel
    class Course(BaseModel):
        id = PrimaryKeyField()  # 课程唯一标识
        title = CharField(null=False)  # 课程名称
        period = IntegerField()  # 学时
        des = CharField()  # 课程描述
    
        class Meta:
            order_by = {'title', }
    
        table_name = 'course'  # 定义数据库中表的名称
    
    
    # 定义一个Teacher表(老师表)。继承于BaseModel
    class Teacher(BaseModel):
        id = PrimaryKeyField()  # 唯一标识
        name = CharField(null=False)  # 名称
        gender = BooleanField()  # 性别
        address = CharField()  # address地址
        course_id = ForeignKeyField(Course, to_field='id', related_name='course')
    
        class Meta:
            order_by = {'name', }
            table_name = 'teacher'  # 定义数据库中表的名称
    
    
    # 执行建表,只需要执行一次
    Teacher.drop_table()
    Course.drop_table()
    
    # peewee.IntegrityError: 错误:  在 "course" 上的更新或删除操作违反了在 "teacher" 上的外键约束 "teacher_course_id_fkey"
    # DETAIL:  键值对(id)=(2)仍然是从表"teacher"引用的.
    
    # 执行建表,只需要执行一次
    # Teacher.delete()
    Course.create_table()
    Teacher.create_table()
    
    # 新增行
    obj1 = Course.create(id=1, title='经济学', period=320, des='文理科学生均可选修')
    # 把数据对象转成字典
    u = model_to_dict(obj1)
    print(u)
    print('通过create()方法添加数据,它会返回一个模型实例:--->', u)
    
    # 把字典转成数据对象
    user_data = {'id': 2, 'username': 'charlie'}
    obj1 = dict_to_model(Course, u)
    print('把字典转成数据对象:---->', obj1.title)
    
    Course.create(id=2, title='大学英语', period=300, des='大一学生必修课')
    Course.create(id=3, title='哲学', period=100, des='必修课')
    Course.create(id=104, title='编译原理', period=100, des='计算机系选修')
    Teacher.create(name='白阵君', gender=True, address='.1.', course_id=1)
    Teacher.create(name='李森', gender=True, address='.2.', course_id=3)
    Teacher.create(name='张雯雯', gender=False, address='.3.', course_id=2)
    Teacher.create(name='李森222', gender=True, address='.344.', course_id=3)
    # 查询一行
    record = Course.get(Course.title == '大学英语')
    print("课程:%s, 学时:%d" % (record.title, record.period))
    
    # 更新
    record.period = 200
    record.save()
    print('更新')
    # 删除
    # 查询一行
    record = Course.get(Course.title == '大学英语')
    print("更新之后---课程:%s, 学时:%d" % (record.title, record.period))
    
    # peewee.IntegrityError: 错误:  在 "course" 上的更新或删除操作违反了在 "teacher" 上的外键约束 "teacher_course_id_fkey"
    # DETAIL:  键值对(id)=(2)仍然是从表"teacher"引用的.
    # 这里想要删除一门课程,但是这门课程可能有一个老师在占用已解决安排上课了!!想要直接删除课程的话,需要先把占用这门课程的老师给删除
    
    # get()方法只能查询一条,且是唯一的一条数据
    teacher_record = Teacher.get(Teacher.course_id == record.id)
    
    print('老师的记录', teacher_record.name)
    teacher_record.delete_instance()
    print('老师被删除记录')
    
    print('删除课程成功!!!')
    print('查询老师!')
    # teacher_record = Teacher.get(Teacher.course_id ==record.id)
    # for i in teacher_record:
    #     print(i.name, i.address)
    
    
    # 查询所有记录
    courses = Course.select()
    for i in courses:
        print(i.id, i.title, i.period, i.des)
    
    # 带条件查询,并将结果按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.des)
    
    # 统计所有课程的平均学时
    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.des)
    
    db.close()
    

    相关文章

      网友评论

          本文标题:python web开发之数据库ORM的 peewee库 动手学

          本文链接:https://www.haomeiwen.com/subject/buvrbxtx.html