可以看到,Pony 把一个列表推导形式的 Python 语句,转换为了对应的 SQL 查询语句,返回了符合条件的数据列表 。相比于使用 where 函数等其他 ORM 采用的查询方式,Pony 的查询语法真正做到了 Pythonic,使得操作数据库表时仿佛在操作原生的 Python 列表 。Pony 还提供了聚合查询:
>>> print max(p.age for p in Person)SELECT MAX("p"."age")FROM "Person" "p"30使用 max 函数,就直接实现了对 Person.age 进行最大值的聚合查询 。
>>> select((p, count(p.cars)) for p in Person)[:]SELECT "p"."id", COUNT(DISTINCT "car-1"."id")FROM "Person" "p"LEFT JOIN "Car" "car-1"ON "p"."id" = "car-1"."owner"GROUP BY "p"."id"[(Person[1], 0), (Person[2], 1), (Person[3], 1)]代码语义十分清晰,查询所有的人,和每人所拥有的车辆数 。这条看似简单的逻辑,翻译成 SQL,就会涉及到 Person 和 Car 模型的 join,以及对于 Person 的 group_by,还有计数的聚合查询和去重问题,可以看到,转换得到的 SQL 语句共5行涉及了众多的 SQL 语法和概念 。Pony 使用一行语义清晰的 Python 代码,就实现了一个较为复杂的 SQL 查询,令人印象深刻 。
另外,排序可以使用 Query 提供的 order_by 实现:
>>> select(p for p in Person).order_by(Person.name)[:2]SELECT "p"."id", "p"."name", "p"."age"FROM "Person" "p"ORDER BY "p"."name"LIMIT 2[Person[3], Person[1]]这里还使用了 [:2] 的语法,实现了 SQL 中的 LIMIT 语法 。
如果你更喜欢使用 lambda 函数,Pony 也提供了 lambda 函数的数据查询方式:
product_list = Product.select(lambda p: p.price > 100)[:]Pony 还提供了自动的去重查询 。当进行数据的单个属性的查询时,我们往往希望查询的是所有出现的值的集合 。Pony 会自动判断当前查询的语义,进行 DISTINCT 去重的添加 。例如,想要查询所有人的名字:
select(p.name for p in Person)在这里,查询语句只查询名字这一个属性,意味着我们想要得到的是所有名字的集合,而对于重名的情况并不关心,Pony 就会自动添加 DISTINCT:
SELECT DISTINCT "p"."name"FROM "Person" "p"对于使用主键查询数据实例,Pony 使用了极为简洁的方括号语法:
customer1 = Customer[123]对于符合主键的模型,这个语法也是可以工作的:
order_item = OrderItem[order1, product1]对于数据的修改和删除也是十分简单的:
Product[123].quantity += 10Order[123].delete()也提供了批量更新和修改:
update(p.set(price=price * 1.1) for p in Productif p.category.name == "T-Shirt")delete(p for p in Product if p.category.name == 'SD Card')

文章插图
Python ORM
总结作为一个 Python 语言的 ORM 框架,以其优雅的接口语法,和智能的自动化处理能力,成为了其他 ORM 框架的有力竞争,值得开发者们进行使用,有兴趣的话还可以对其实现源码进行学习研究,进行开源贡献 。
推荐阅读
- 外包面试之旅
- 最赚钱的10家上市公司:程序员群体“含金量”第一
- 优傲机器人与如影智能签订战略协议,加速机械臂进入消费级市场
- 智能硬件不止树莓派,八款优秀智能硬件开源项目推荐
- 产后什么时候练瑜伽最好
- 喝绿茶的最佳时间,喝狗脑贡茶的最佳时间
- 女生学跆拳道到底好吗
- 跑步的最佳时候是什么
- 美国探测器回望地球 现在距离地球最远的探测器
- 电影|《侏罗纪世界3》公布最终预告片:人龙对决命悬一线
