引出重写的原因,我们是通过软删除的方式来删除数据的(即通过status标识来确定数据是否作废)

flask_sqlalchemy 批量update flask sqlalchemy query_python 重写

flask_sqlalchemy 批量update flask sqlalchemy query_BaseQuery_02

那么这样的话,我们每一次查询的时候都要写上条件status=1很繁琐。我们可以重写filter_by方法

如上图所示我们现在使用的查询方式并不是SQLAlchemy原生的查询方式,而是flask_sqlalchemy(是对原生SQLAlchemy的一个封装),是因为flask觉得原生的SQLAlchemy不是很方便,就以原生的为基础自己封装了一个flask_sqlalchemy实现了它自己的一些更加方便的查询。所以说上面的query对象是flask_sqlalchemy下面的一个对象。

下面我们flask_sqlalchemy查看源码

flask_sqlalchemy 批量update flask sqlalchemy query_flask_sqlalchemy_03

在__init__文件的407行有一个BaseQuery

flask_sqlalchemy 批量update flask sqlalchemy query_filter_by_04

可以看出是继承了orm.Query,这个就是原生SQLAlchemy包里面的一个对象。我们可以看到在BaseQuery下面是没有实现filter_by方法的。下面我们在看一下orm.Query的源码

flask_sqlalchemy 批量update flask sqlalchemy query_flask_sqlalchemy_05

而在这个文件的1559行就找到了filter_by

flask_sqlalchemy 批量update flask sqlalchemy query_filter_by_06

可以看到他接收一组参数**kwargs,这个参数就是我们下图传入进来的键值对。kwargs是一个字典!!!

flask_sqlalchemy 批量update flask sqlalchemy query_BaseQuery_07

然后在filter_by内部进行了下图源码的处理(我们这里不用管)

flask_sqlalchemy 批量update flask sqlalchemy query_BaseQuery_08

如果说我们只需要自己实现filter_by,然后在filter_by的内部加上status=1,最后在调用基类的filter_by方法,就可以完成我们的覆盖改写。

flask_sqlalchemy 批量update flask sqlalchemy query_flask_sqlalchemy_09

下面开始敲代码啦:

首先导入flask_sqlalchemy的BaseQuery

flask_sqlalchemy 批量update flask sqlalchemy query_filter_by_10

flask_sqlalchemy 批量update flask sqlalchemy query_BaseQuery_11

上图只是仅仅实现我们自己的逻辑了。我们还需要完成filter_by原有的逻辑。

调用基类下面的filter_by方法:

flask_sqlalchemy 批量update flask sqlalchemy query_python 重写_12

在传入字典的时候我们必须要对字典进行解包所以要传入两个*号

可以看到基类里面是有return的,所以我们要是不return就会有问题,我们需要return一下

flask_sqlalchemy 批量update flask sqlalchemy query_python 重写_13

现在我们就完成了自定义的Query,但是还没有替换原来的BaseQuery,就要去看一下源码。flask_sqlalchemy给了我们一个替换他原有BaseQuery的机会。这个机会就在flask_sqlalchemy这个他实例化的地方。下面我们在看一次源码:

flask_sqlalchemy 批量update flask sqlalchemy query_python 重写_14

点进去看到下图:

flask_sqlalchemy 批量update flask sqlalchemy query_python 重写_15

可以看到在她的构造函数里面是允许传入一个自己的BaseQuery的

flask_sqlalchemy 批量update flask sqlalchemy query_flask_sqlalchemy_16

这样我们就用自己定义的Query替代了flask_sqlalchemy的BaseQuery

上图就完成了重写flask_sqlalchemy的filter_by方法

所以当我们再调用query对象下面的filter_by方法的时候,就不是调用原来BaseQuery下面的filter_by了,而是调用我们自己改写的这个filter_by。

flask_sqlalchemy 批量update flask sqlalchemy query_BaseQuery_17

在替换完成之后我们所有的filter_by中都不需要传入status=1了。