Pony的left-join

简介: Pony的left-join

1、前言


上篇我们了解了Pony ORM框架的基本用法,今天我们一起来学习下pony的left-join。

left-join使我们日常工作中用的最多的多表联合查询语句,左连接即有两个表A、B,A的keya是B的keyb的外键,那么我们可以通过left-join将B表左连接到A表的左边,通过A表的keya找到能够匹配到keyb的B表内容,未匹配成功的行使用None(null)填充。这样就实现了左连接的查询。


左连接以左表为主,所以左表未匹配成功的行使用None填充。但是结果表的字段我们可以根据自己的需要去选择A表或者B表的字段组合完成。


2、快速开始


2.1、理论分析


我们继续使用上篇的数据库表,对于person和car两张表,person的cars和car的关系是一对多;而car的owner和person的关系是一对一。


当我们需要查询哪些车有主人,即哪些人有车时,就需要用到person left-join car;

注意:查询结果以car表为主,即未匹配成功的数据将会被None填充。另,car中owner无数据的将会被过滤掉。


2.1.1、原始表


person表:


# person表:
# 13  phyger-0  18  
# 14  phyger-1  18  
# 15  phyger-2  18  
# 16  phyger-3  18  
# 17  phyger-4  18  
# 18  phyger-5  18  
# 19  phyger-6  18  
# 20  phyger-7  18  
# 21  phyger-8  18  
# 22  phyger-9  18  
# 23  phyger-10 18
复制代码


car表:


# car表
# 1 byd 宋Pro-Dmi  NULL  
# 2 吉利  星越L     13  
# 3 哈佛  H6        13
复制代码


2.1.2、person left join car


# person  left-join  car  之后:
# p.id ---------------------------------- c.owner
# 13  phyger-0  18  1 byd 宋Pro-Dmi       NULL(x)
# 14  phyger-1  18  2 吉利  星越L          13  (√)  //和13匹配成功一条
# 15  phyger-2  18  3 哈佛  H6            13  (√)   //又和13匹配成功一条
# 16  phyger-3  18  
# 17  phyger-4  18  
# 18  phyger-5  18  
# 19  phyger-6  18  
# 20  phyger-7  18  
# 21  phyger-8  18  
# 22  phyger-9  18  
# 23  phyger-10 18
复制代码


2.1.3、p的id和c的owner匹配后


# on p.id==c.owner 匹配之后:
# p.id ---------------------------------- c.owner
# 13  phyger-0  18  2 吉利    星越L         13
# 13  phyger-0  18  2 哈佛    H6            13  
# 14  phyger-1  18  ↘ 全部None补全
# 15  phyger-2  18  
# 16  phyger-3  18  
# 17  phyger-4  18  
# 18  phyger-5  18  
# 19  phyger-6  18  
# 20  phyger-7  18  
# 21  phyger-8  18  
# 22  phyger-9  18  
# 23  phyger-10 18
复制代码


2.2、代码实现


首先,我们写一个函数去实现left-join。因为需要使用db_session去解决数据库的优雅连接问题,所以我们使用函数去做。


# left-join,结果以car表(左表)为主,结果的结构自己定义
@db_session
def lftj():
    '''
    @note: 左连接即将后表链接在前表的左边
    @code: left_join((p, c.name) for p in Person for c in p.cars)
         此段代码的意思是:
            将car表连接在person表的左边,当p的id等于c的owner时,匹配成功。(即找到有车的人)
    @对应的SQL:        
            SELECT "p", "c"."name"
            FROM "person" "p"
            LEFT JOIN "car" "c"
            ON "p"."id" = "c"."owner"
            GROUP BY "p"."id"
    '''
    for i in left_join((p, c.name) for p in Person for c in p.cars):
        print(i)
复制代码


以上代码的核心就是left_join((p, c.name) for p in Person for c in p.cars),首先这段代码的返回值是一个query对象,是可迭代的;其次,left_join的第一个参数就是结果表结构,即p对象和c的name两列;for p in Person就相当于FROM "person" "p",即从Person表查询,别名为p;for c in p.cars最重要,它表达的意思就是left join Car且ON "p"."id" = "c"."owner",最终返回一个query对象。


然后我们对这个query对象进行遍历打印。


代码运行结果:


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


这个查询结果表示,所有车有主人的是吉利和哈佛;而且吉利和哈佛的主人都是Person[13]。


对于这个结果表结构,我们可以在left-join的第一个参数中进行定义。


...
for i in left_join((p.name,p.age, c.name) for p in Person for c in p.cars):
        print(i)
复制代码


以上代码的执行结果:


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


2.3、去掉None


我想实际开发中,我们经常会需要将这些未匹配成功的数据过滤掉,当然我们可以通过left-join后进行过滤,但是这样就多了一步,值得高兴的是Pony的select就可以同时实现left-join和过滤None的效果。


# 联合查询,结果是交集,结果的结构自己定义
@db_session
def xx():
    for i in select((p.name,p.age, c.name) for p in Person for c in p.cars):
        print(i)
if __name__ == '__main__':
    db.generate_mapping(create_tables=True)
    xx()
复制代码


通过上述代码,我们可以看到select和left-join的语法完全一样,只是结果有区别。


代码执行结果:

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


3、最后


其实只要了解了left-join的原理,不论我们使用何种ORM框架,其底层SQL都是一致的。

相关文章
反诈中心拦截网站域名措施与申诉方法
近几年随着互联网不断发展,也伴随着一些网络诈骗的问题,反诈中心打击违规诈骗网站、诈骗APP、标记诈骗手机号,这一些措施取得一定的效果,从去年开始严厉审核一些违规网站,也不排除于批量审核会出现一定的偏差,可能会出现审核不到位的情况,这里我表达自己的一些看法。
3764 0
反诈中心拦截网站域名措施与申诉方法
|
2月前
|
编解码 自然语言处理
通义万相开源14B数字人Wan2.2-S2V!影视级音频驱动视频生成,助力专业内容创作
今天,通义万相的视频生成模型又开源了!本次开源Wan2.2-S2V-14B,是一款音频驱动的视频生成模型,可生成影视级质感的高质量视频。
700 29
|
11月前
|
运维 监控 安全
数字孪生与矿业:提高开采效率
数字孪生技术在矿业领域的应用正逐步改变传统采矿模式,通过创建矿山的虚拟模型并实时集成数据,提高开采效率、优化资源利用、降低安全风险。本文深入探讨其在精准勘探、优化开采计划、实时监控与故障预警等方面的应用,以及带来的优势和典型案例。
|
存储 移动开发 HTML5
SessionStorage 和 LocalStorage 有什么区别?
SessionStorage 和 LocalStorage 有什么区别?
581 3
|
5月前
|
弹性计算 NoSQL 数据库
阿里云服务器如何备份数据?
阿里云服务器数据备份有多种方法,用户可按需选择。主要方式包括:1)快照备份,创建云盘的时间点拷贝,支持定期备份与数据恢复;2)数据库备份DBS,适用于多种环境的数据库备份,涵盖本地及多云场景;3)云备份Cloud Backup,提供统一灾备平台,支持ECS整机、数据库、文件系统等全方位备份,保障数据安全。
|
安全 网络协议 网络安全
BUUCTF:Misc 解析(二)
BUUCTF:Misc 解析(二)
|
11月前
|
前端开发 Java 数据格式
SpringBoot中定义Bean的几种方式
本文介绍了Spring Boot中定义Bean的多种方式,包括使用@Component、@Bean、@Configuration、@Import等注解及Java配置类。每种方式适用于不同的场景,帮助开发者高效管理和组织应用组件。
365 0
|
存储 容灾 Linux
服务器备份
服务器备份
406 2
|
存储 弹性计算 应用服务中间件
阿里云经济型e与通用算力型u1实例长效特价云服务器解析,性能与性价比的完美平衡
阿里云目前有两款深受个人和普通企业用户喜欢的特价云服务器,ECS 经济型e实例2核2G,3M固定带宽,40G ESSD Entry云盘,仅需99元1年。ECS u1实例2核4G,5M固定带宽,80G ESSD Entry盘,仅需199元1年。新老同享,活动期间新购、续费同价。很多用户关心这两款云服务器性能怎么样?本文将对阿里云2024年推出的特价云服务器进行深度解析,从性能、价格、适用场景等多个维度进行详细探讨,以供选择参考。
阿里云经济型e与通用算力型u1实例长效特价云服务器解析,性能与性价比的完美平衡
|
存储 算法 机器人
Threejs路径规划_基于A*算法案例V2
这篇文章详细介绍了如何在Three.js中使用A*算法进行高效的路径规划,并通过三维物理电路的实例演示了路径计算和优化的过程。
402 0