Flask Python中使用filter和filter_by进行模糊查询和多条件数据库查询

数据库(sqlalchemy)多条件查询

  • 前言
  • 一、filter、filter_by实现过滤查询
  • 1、filter_by()
  • 基础查询
  • 并且查询(多条件查询)
  • 2、filter()
  • like:模糊查询
  • and:并且查询
  • or:或者查询
  • 二、all(),first(),get()的使用
  • 三、分页和排序
  • 分页
  • 排序
  • 四、聚合查询(count、sum、avg)
  • 五、关系查询(一对一,一对多)
  • 前言

    SQLAlchemy的包使用文档
    SQLAlchemy Documentation


    这里有跟select相搭配使用的各种方法嘞

    上一篇:模型(model)Flask-SQLAlchemy的使用,在这里已经分享了安装以及初步使用SQLAlchemy包。在实际项目中,经常有搜索的功能,这里就分享一下模糊查询的使用

    一、filter、filter_by实现过滤查询

    1、filter_by()

    在文档中可以看到,filter_by()的使用方式

    找到源码可以看到实现逻辑:

        def filter_by(self, **kwargs: Any) -> Self:
            from_entity = self._filter_by_zero()
    
            clauses = [
                _entity_namespace_key(from_entity, key) == value
                for key, value in kwargs.items()
            ]
            return self.filter(*clauses)
    

    可以看出,filter_by() 只接受键值对参数,所以 filter_by() 不支持><(大于和小于)和 and_、or_查询

    基础查询

    查询文章类型相等的

        resource_lists: List[models.Resource] = (models.Resource.query
                                                 .filter_by(r_type=0 )
                                                 .all())
    
    并且查询(多条件查询)
    # 获取所有博客文章列表
    @blog_base_blueprint.route('/search_reousrce', methods=['POST'])
    def search_resource():
        keyword = request.form.get('keyword')
        type= request.form.get('type')
    
        if not keyword or type:
            return jsonify({
                'code': 0,
                'msg': '搜索词/类型不能为空',
            })
    
    
        resource_lists: List[models.Resource] = (models.Resource.query
                                                 .filter_by(r_type=0 )
                                                 .filter_by(title = keyword)
                                                 .all())
    
        return jsonify({
            'code': 0,
            'msg': 'success',
            'data': {
                "resource_list": [resource.to_format() for resource in resource_lists]
            }
        })
    

    若是或者条件查询,filter_by()方法就不满足不了需求了,需要使用filter()

    2、filter()

    like:模糊查询

    查询标题包含特定词的

    keyword = request.form.get('keyword')
    resource_lists: List[models.Resource] = (models.Resource.query
                                                 .filter(models.Resource.title.like('%{}%'.format(keyword) ))
                                                 .all())
    
    and:并且查询
  • 链式调用多个filter条件,每个filter都会在之前的结果集上进行筛选。那并且查询就好处理了,比如:我要查询标题中含有某些关键词并且内容类型为医学文献的:
  • def search_resource():
        keyword = request.form.get('keyword')
        type= request.form.get('type')
        resource_lists: List[models.Resource] = (models.Resource.query
                                                 .filter(models.Resource.title.like('%{}%'.format(keyword) ))
                                                 .filter(models.Resource.r_type==type)
                                                 .all())
    
  • 使用sqlalchemy中的and_实现
  • from sqlalchemy import and_
    def search_resource():
        keyword = request.form.get('keyword')
        type= request.form.get('type')
        resource_lists: List[models.Resource] = (models.Resource.query
                                                 .filter(and_(models.Resource.title.like('%{}%'.format(keyword) ), models.Resource.r_type==type))
                                                 .all())
    
    or:或者查询

    查询挑剔中含有特定关键词的,或者内容类型为医学指南的:

    from sqlalchemy import or_
    
    def search_resource():
        keyword = request.form.get('keyword')
        type= request.form.get('type')
    
        if not keyword :
            return jsonify({
                'code': 0,
                'msg': '搜索词/类型不能为空',
            })
    
        resource_lists: List[models.Resource] = (models.Resource.query
                                                 .filter(or_(models.Resource.title.like('%{}%'.format(keyword) ), models.Resource.r_type==type))
                                                 .all())
    
        return jsonify({
            'code': 0,
            'msg': 'success',
            'data': {
                "resource_list": [resource.to_format() for resource in resource_lists]
            }
        })
    

    二、all(),first(),get()的使用

    #获取所有的数据
        models.Resource.query.all()
    
    #获取第一条数据
        models.Resource.query.first()
        
    #需要传递参数,查询数据的主键跟参数一样
        models.Resource.query.get(3)
    

    三、分页和排序

    分页

    #跟php差不多,都是使用offset和limit,下面意思是跳过第二条开始查询,然后获取3条记录
     models.Resource.query.offset(2).limit(3)
    

    这里有个常见的问题,就是TypeError: unsupported operand type(s) for -: ‘str‘ and ‘int‘,点击可以查看解决方案

    排序

    #使用order_by方法排序,有desc和asc排序方式,直接可用
       models.Resource.query.order_by(models.Resource.id.desc()).all()
    

    四、聚合查询(count、sum、avg)

    	resource_lists =db.session.query(func.count(models.Resource.id)).all()
    
        print(resource_lists)
        print(resource_lists[0][0])
    

    打印resource_lists可以发现返回值是这样的:

    所以想获取到最终的值需要如上方式处理一下,类似的还有方法sum()、avg()

    五、关系查询(一对一,一对多)

    新开了一篇,Flas中模型关联实现,点击前往

    作者:ignativs amor

    物联沃分享整理
    物联沃-IOTWORD物联网 » Flask Python中使用filter和filter_by进行模糊查询和多条件数据库查询

    发表回复