Pony,个性的ORM框架!

简介: Pony,个性的ORM框架!

1、前言


前面,我们已经了解了peewee、Sqlalchemy等众ORM框架了,今天我们继续介绍一款个性独特的ORM框架,它就是Pony。怎么样,是不是大名鼎鼎,未见其人,先闻其声,不得不说,这个ORM库的名字起的是真的好,但是其实际使用体验怎么样呢?我们一起来看看吧。


2、快速开始


2.1、安装Pony

pip install pony
复制代码


2.2、链接数据库


新建文件pony_demo.py并输入以下代码:


from pony.orm import *
db = Database()
db.bind('sqlite','mydb.db',create_db=True)
复制代码


直接执行代码:python pony_demo.py,你会发现,pony自动帮我们在当前文件夹下创建了一个数据库文件mydb.db。这就是create_db参数的作用,当数据库不存在的时候自动帮我们创建。


2.3、创建模型类(表)


实际开发中,比如在Django、Flask、FastApi中都是用模型类来描述一个表的结构的。Pony也和其他ORM一样使用模型类来定义表结构,但是其写法和其他ORM框架稍有区别。


from pony.orm import *
db = Database()
db.bind('sqlite','mydb.db',create_db=True)
# 定义一个表:person
class Person(db.Entity):
    _table_ = 'person' # 表名
    # 当我们不定义主键ID的时候,pony会和大多数orm框架一样自动帮我们补全
    # id = PrimaryKey(int, auto = True)
    name = Required(str, 30, default = "未知")
    age = Optional(int)
    car = Set('Car') # 以集合的形式关联Car表,即一个人多个车
class Car(db.Entity):
    _table_ = 'car' 
    name = Required(str)
    typa = Required(str)
    owner = Required(Person) # 关联Person表,即一个车的主人只有一个
if __name__ == '__main__':
    # 1.查看表结构
    show(Car)
复制代码


如上,你会看到,不同于其他ORM框架的字段声明,Pony使用了必选(Required)和可选(Optional)以及表关联的这种方式。


执行如上代码,我们就能看到Car表的表结构:


网络异常,图片无法展示
|


主键ID是Pony帮我们自动添加的,且自增。


此时的数据库中还未创建表;


网络异常,图片无法展示
|


2.4、将表映射到数据库


以上内容我们只是定义了表结构(模型),现在我们需要将表映射到数据中去。


if __name__ == '__main__':
    # 1.查看表结构
    # show(Car)
    # 2.将模型类映射到数据库,以表的形式展现
    db.generate_mapping(create_tables=True) # 如果表存在则对表结构进行更新,如果不存在则创建
复制代码


代码执行后查看数据库状态:


网络异常,图片无法展示
|


此时,我们就可以对数据库表进行读写操作了。


为了方便数据库的连接(db_session)管理,我们后续都使用pony为我们提供的db_session对数据库连接进行管理。(如此一来,我们不需要关注数据库的session建立和关闭,只需要专注于业务本身即可。)


2.5、CRUD之C


这里我们使用db_session对会话进行优雅管理,然后创建一个函数,在函数中实现对person的创建。


...
@db_session
def create_person(name,age):
    perObj = Person(name=name,age=age)
...
if __name__ == '__main__':
    # 3.CRUD之C
    db.generate_mapping(create_tables=True)
    create_person('phyger',18)
复制代码


执行代码后,我们查看下数据库的内容:


网络异常,图片无法展示
|


数据已经成功插入。


2.6、CRUD之R


参数C,我们在R中也是通过db_session对person表中的数据进行查询。


...
@db_session
def get_person(name):
    persObj = Person.select(name=name)
    print(persObj.first().age)
...
if __name__ == '__main__':
    # 4.CRUD之R
    db.generate_mapping(create_tables=True)
    get_person('phyger')
复制代码


代码执行结果:


网络异常,图片无法展示
|


2.7、CRUD之U


在完成了上述步骤后,我们继续对数据表中的数据进行更新操作。


...
@db_session
def put_person(name,new_name=None,new_age=None):
    persObj = Person.select(name=name)
    if new_name:
        persObj.first().name=new_name
    if new_age:
        persObj.first().age=new_age
    print('更新成功!')
...
if __name__ == '__main__':
    # 5.CRUD之U
    db.generate_mapping(create_tables=True)
    get_person('phyger')
    put_person('phyger',new_name='new_phyger')
    get_person('phyger')
复制代码


代码执行结果:


网络异常,图片无法展示
|


执行代码的最后一步报错了,为什么呢?因为我们修改了phyger的name后,还用旧的名称去查询,所以查询不到。


我们看下数据库中是否修改成功:


网络异常,图片无法展示
|


我们使用新名称查询即可查询成功了。


2.8、CRUD之D


在完成测试后,我们想要将数据表中的数据删除,怎么做呢?


我们先给数据表预置上11条数据:


网络异常,图片无法展示
|


...
@db_session
def del_person(name):
    delete(p for p in Person if p.name==name) # 根据名称进行删除
...
if __name__ == '__main__':
    # 6.CRUD之D
    db.generate_mapping(create_tables=True)
    del_person('phyger-8')
复制代码


指定删除name为phyger-8的数据,执行代码,刷新数据表查看结果:


网络异常,图片无法展示
|


我们发现删除已经成功!


3、进阶


3.1、完善查询


上面的方法只能根据name进行查询,我们对其进行优化,使得能够使用id,name和age等参数进行查询。


@db_session
def get_person(name=None,id=None,age=None):
    if name:
        for p in Person.select(name=name):
            print(p.id,p.name)
    if id:
       for p in Person.select(id=id):
            print(p.id,p.name)
    if age:
       for p in Person.select(age=age):
            print(p.id,p.name)
复制代码


如此,我们即能够根据不同的查询参数进行查询了。


3.2、批量删除


我们根据上面的查询方法,如果根据年龄18查询将能够查询到所有的对象集合。类似的删除也可以如此来实现。


@db_session
def del_person(name=None,idd=None,age=None):
    if name:
        delete(p for p in Person if p.name==name)
    if idd:
        delete(p for p in Person if p.id==idd)
    if age:
        delete(p for p in Person if p.age==age)
if __name__ == '__main__':
    # 批量删除
    db.generate_mapping(create_tables=True)
    del_person(age=18)
复制代码


其实原本的方式也是支持批量删除的,这里只是增加了多种删除字段。


3.3、表结构变更如何实现


目前最新发布的pony 0.7版本还不支持数据库迁移(migrate),但是我们可以手动对表结构进行更改。0.8版本后将会支持数据库迁移,了解详情点击:/pony/pony/migrate


3.4、分页


作为一个成熟的ORM框架,分页功能必不可少。


@db_session
def person_page(num,size):
    PObj=Person.select()
    for p in PObj.page(num,size):
        print(p.name)
if __name__ == '__main__':
    # 7.分页
    db.generate_mapping(create_tables=True)
    person_page(1,5)  # 第一页,单页大小5   0到4
    person_page(2,3)  # 第二页,单页大小3   3,4,5
复制代码


其中num是页码,size是每页的大小即pagesize。


网络异常,图片无法展示
|


3.5、表关联


上面,我们定义了person和car两张表,car的owner和person关联,使用外键id关联。现在我们就一起来看下如何使用。


普通创建car对象,即不做和person的关联。


@db_session
def create_car(name, typa, owner=None):
    if owner:
        carObj = Car(name=name, typa=typa, owner=owner)
    else:
        carObj = Car(name=name, typa=typa)
if __name__ == '__main__':
    # 8、创建Car-1
    db.generate_mapping(create_tables=True)
    create_car(name='byd',typa='宋Pro-Dmi')
复制代码


创建带person关联关系的car对象。


if __name__ == '__main__':
    # 8、创建Car-2
    db.generate_mapping(create_tables=True)
    pp = get_person(id=14)
    print(pp)
    create_car(name='吉利',typa='星越L',owner=pp.id)
复制代码


以上两段代码执行完成,查看car数据表内容:


网络异常,图片无法展示
|


联合查询,即根据用户查到其ID,在根据其ID查询名下的车。


@db_session
def get_car(name=None, id=None, owner=None):
    if name:
        for c in Car.select(name=name):
            print(c.id, c.name)
    if id:
        for c in Car.select(id=id):
            print(c.id, c.name)
    if owner:
        for c in Car.select(owner=owner):
            print(c.id, c.name)
if __name__ == '__main__':
    # 9、表关联的查询
    db.generate_mapping(create_tables=True)
    ps = get_person(name='phyger-0')
    get_car(owner=ps.id)
复制代码


代码执行结果:


网络异常,图片无法展示
|


如上,我们得知phyger-0名下有两辆车,分别是吉利和哈佛。


Car数据表内容如下:


网络异常,图片无法展示
|


以上就是今天的全部内容了。

相关文章
|
5月前
|
开发者
告别繁琐代码,JSF标签库带你走进高效开发的新时代!
【8月更文挑战第31天】JSF(JavaServer Faces)标准标签库为页面开发提供了大量组件标签,如`<h:inputText>`、`<h:dataTable>`等,简化代码、提升效率并确保稳定性。本文通过示例展示如何使用这些标签实现常见功能,如创建登录表单和展示数据列表,帮助开发者更高效地进行Web应用开发。
56 0
|
5月前
|
Java 测试技术 容器
从零到英雄:Struts 2 最佳实践——你的Web应用开发超级变身指南!
【8月更文挑战第31天】《Struts 2 最佳实践:从设计到部署的全流程指南》深入介绍如何利用 Struts 2 框架从项目设计到部署的全流程。从初始化配置到采用 MVC 设计模式,再到性能优化与测试,本书详细讲解了如何构建高效、稳定的 Web 应用。通过最佳实践和代码示例,帮助读者掌握 Struts 2 的核心功能,并确保应用的安全性和可维护性。无论是在项目初期还是后期运维,本书都是不可或缺的参考指南。
62 0
|
5月前
|
前端开发 安全 Java
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
35 0
|
7月前
|
存储 Python
技术经验分享:20220719uiautomation之二三
技术经验分享:20220719uiautomation之二三
51 0
MyBatis这样用,同事直呼哇塞,堪称最佳实践
MyBatis是一款非常流行的ORM框架,相信很多小伙伴都在使用。我们经常会把它和MyBatis-Plus或者MBG一起使用,用多了之后对于其一些常规操作就不太熟悉了。最近总结了下MyBatis的实用用法和技巧,希望对大家有所帮助!
|
SQL 缓存 数据可视化
不必再造轮子了, 这款代码生成器(一键生成)真的很强
不必再造轮子了, 这款代码生成器(一键生成)真的很强.对于百余张表的数据库,使用代码生成器让开发事半功倍。
465 0
|
JSON 前端开发 JavaScript
解放双手!推荐一款阿里开源的低代码工具,YYDS
之前分享过一些低代码相关的文章,发现大家还是比较感兴趣的。之前在我印象中低代码就是通过图形化界面来生成代码而已,其实真正的低代码不仅要负责生成代码,还要负责代码的维护,把它当做一站式开发平台也不为过!最近体验了一把阿里开源的低代码工具LowCodeEngine,确实是一款面向企业级的低代码解决方案,推荐给大家! LowCodeEngine简介 LowCodeEngine是阿里开源的一套面向扩展设计的企业级低代码技术体系,目前在在Github上已有4.7K+Star。这个项目大概是今年2月中旬开源的,两个月不到收获这么多Star,确实非常厉害!
|
数据安全/隐私保护
五款功能强大的国产软件,常常被误认为是外国人开发的
今日的栽种,明日的果实,今天继续分享五个被误以为是国外软件的国产软件。
213 0
五款功能强大的国产软件,常常被误认为是外国人开发的
|
Java 数据库连接 mybatis
Mybatis-Plus 真好用(乡村爱情加持)
写在前面 MyBatis的增强方案确实有不少,甚至有种感觉是现在如果只用 “裸MyBatis”,不来点增强插件都不好意思了。这不,在上一篇文章《Spring Boot项目利用MyBatis Generator进行数据层代码自动生成》 中尝试了一下 MyBatis Generator。
1843 0