之前做查询一直觉得直接拼 SQL 比较方便,用了 SQLAlchemy 的 ORM 查询之后,发现也还可以,还提高了可读性。
这篇文章主要说说 SQLAlchemy 常用的 ORM 查询方式,偏实践。看了之后,对付开发中的查询需求,我觉得可以满足不少。
为方便说明,假设有如下数据
图书表 books
分类表 categories
ORM 对象定义如下
注意:本文 Python 代码在以下环境测试通过
Python 3.6.0
PyMySQL 0.8.1
SQLAlchemy 1.2.8
好了,下面进入正题。
1 根据主键获取记录
当我们获取图书的详情时,很容易用到。
直接 get(primary_key) 就得到结果
当然,这样也可以
不过,还是前一种方式简洁一些。
2 AND 查询
我们最常用到的就是这种查询,比如我要获取 为 1 且价格大于 35 的书
执行后,得到结果
filter() 里面的条件默认是使用 AND 进行连接,毕竟这最常用嘛。所以说,换成这样用也是没有问题的
不过,通常来说,如果条件全是用 AND 连接的话,没必要显式的去用 。
如果条件都是等值比较的话,可以使用 方法,传入的是关键字参数。
查询 等于 1 且价格等于 31.8 的图书,可以这样
结果
这种方式相对于 filter() 来说,书写要简洁一些,不过条件都限制在了等值比较。
不同情况选择合适的就好。
3 常用方法
除了上面使用的 get()、first()、all() 外,还有下面的一些方法比较常用。
one() 只获取一条记录,如果找不到记录或者找到多条都会报错
count() 返回记录条数
结果
limit() 限制返回的记录条数
结果
distinct() 与 SQL 的 distinct 语句行为一致
结果
将记录按照某个字段进行排序
结果
scalar() 返回调用 one() 后得到的结果的第一列值
结果
exist() 查看记录是否存在
结果
4 OR 查询
通过 OR 连接条件的情况也多,比如我要获取 等于 1 或者价格大于 35 的书
执行,得到结果
使用方式和 AND 查询类似,从 sqlalchemy 引入 ,然后将条件放入就 OK 了。
5 AND 和 OR 并存的查询
现实情况下,我们很容易碰到 AND 和 OR 并存的查询。比如,我现在要查询价格大于 55 或者小于 25,同时 不等于 1 的图书
结果
又如,查询图书的数量,图书满足两个要求中的一个即可:一是 大于 5;二是 小于 2 且价格大于 40。可以这样
结果
6 巧用列表或者字典的解包给查询方法传参
开发中,我们经常会碰到根据传入的参数构造查询条件进行查询。比如
如果接收到非 0 的 ,需要限制 等于 0
如果接收到非 0 的 price,需要限制 price 等于传入的 price
如果接收到非 0 的 ,需要限制 price 大于等于
如果接收到非 0 的 ,需要限制 price 小于等于
我们就可以编写类似的代码
结果
OR 查询类似,将列表解包传给 即可。
如果需求更复杂,AND 和 OR 都可能出现,这个时候根据情况多建几个列表实现。这里只向大家说明大致的思路,就不举具体的例子了。
当然,如果都是等值查询的话,比如只有这两种情况
如果接收到非 0 的 ,需要限制 等于 0
如果接收到非 0 的 price,需要限制 price 等于传入的 price
可以使用字典的解包给 传参
结果
7 其它常用运算符
除了上面看到的 ==、>、>=、
IN
INSTR()
LIKE
NOT
上面的 IN、INSTR、 、LIKE 都可以使用 ~ 符号取反。比如
8 查询指定列
查询名称包含「简史」的图书的 ID 和名称。如下
结果
9 内连接、外连接
9.1 内连接
获取分类为「科技」,且价格大于 40 的图书
结果
统计各个分类的图书的数量
结果
9.2 外连接
为方便说明,我们仅在这一小节中向 books 表中加入如下数据
查看 ID 大于等于 9 的图书的分类信息
结果
注意最后一条记录。
10 打印 SQL
当碰到复杂的查询,比如有 AND、有 OR、还有连接查询时,有时可能得不到预期的结果,这时我们可以打出最终的 SQL 帮助我们来查找错误。
以上一节的外连接为例说下怎么打印最终 SQL
结果
至此,SQLAlchemy ORM 常用的一些查询方法和技巧已介绍完毕,希望能帮助到有需要的朋友。
领取专属 10元无门槛券
私享最新 技术干货