【Python】单表多功能查询的SQL封装

简介: 【Python】单表多功能查询的SQL封装

前言


因为最近业务问题,面临大批量的条件查询、排序、分页、字段筛选,所以用原生sql写了这么一个封装。


适用范围


前端查询:包括分页、排序、条件、字段筛选。

后端查询:单表查询直接使用。

数据库查询:自动生成SQL语句,可直接使用。


功能以及接口使用


参数介绍


‘condition’:[]

解释:参数由列表输入:[‘name@like:小明’,year@>:16] '@‘和’:‘为固定格式,后台代码用其进行通配符,@前为字段名,’:'后为内容。包含 !=,=,>,>=,<,<=,in,notin,like。

‘orderby’:[]

解释:参数由列表输入:['date@desc,‘name@asc’] @为固定格式。

‘exclude’:[]

解释:参数由列表输入:[‘remark’,‘name’] 数据为不包含的字段名。

‘page’:int

解释:参数为页数,类型为整型。

‘pagesize’:int

解释:参数为每页的大小,类型为整型。

注意:不需要的字段可以不给


源码及使用说明


sqlcomment.py:封装的SQL代码

import re
def querycomment(param:dict,tablename:str,cursor,cursorclass):
    '''
    :param param:
    :param tablename:
    :param cursor:
    :param cursorclass:
    :return: sql,sql_count
    '''
    sql = f'select * from {tablename}'
    if v := param.get('exclude'):
        if isinstance(v,list) and len(v) != 0:
            tup = tuple(v)
            if len(tup) == 1:
                tup = str(tup).replace(',','')
            str_ = f"CONCAT(' select ',GROUP_CONCAT(COLUMN_NAME),' from ', '{tablename}',' ;')"
            include_col = f"SELECT {str_} FROM information_schema.COLUMNS WHERE table_name = '{tablename}' and COLUMN_NAME != {tup}"
            cursor.execute(include_col)
            if cursorclass == 'DictCursor':
                sql = cursor.fetchone()[str_].replace(';', '')
            elif cursorclass == 'Cursor':
                sql = cursor.fetchone()[0].replace(';','')
    if condition:=param.get('condition'):
        print(condition)
        if isinstance(condition,list) and len(condition) != 0:
            condi_sql = ''
            for c in condition:
                re_content = re.findall("(.*?)@(.*?):(.*?)$", c.replace(' ', ''))[0]
                try:
                    tuple_ = tuple(eval(re_content[2]))
                except:
                    tuple_ = re_content[2]
                if re_content[1] == 'notin':
                    if 'where' in condi_sql:
                        condi_sql += f' and {re_content[0]} not in {tuple_}'
                    else:
                        condi_sql += f' where {re_content[0]} not in {tuple_}'
                elif re_content[1] == 'like':
                    if 'where' in condi_sql:
                        condi_sql += f' and {re_content[0]} like "%{re_content[2]}%"'
                    else:
                        condi_sql += f' where {re_content[0]} like "%{re_content[2]}%"'
                elif re_content[1] == 'in':
                    if 'where' in condi_sql:
                        condi_sql += f' and {re_content[0]} in {tuple_}'
                    else:
                        condi_sql += f' where {re_content[0]} in {tuple_}'
                else:
                    if 'where' in condi_sql:
                        condi_sql += f" and {re_content[0]} {re_content[1]} '{re_content[2]}'"
                    else:
                        condi_sql += f" where {re_content[0]} {re_content[1]} '{re_content[2]}'"
            sql += condi_sql
    find_col = re.findall(r'select (.*?) from', sql)[0]
    sql_count = sql.replace(find_col, 'count(*)')
    if orderby := param.get('orderby',[]):
        if orderby != []:
            order_sql = ' order by '
            flag = False
            for order in orderby:
                re_content = re.findall("(.*?)@(.*?)$", order.replace(' ', ''))[0]
                if flag:
                    order_sql += f',{re_content[0]} {re_content[1]}'
                    continue
                order_sql += f'{re_content[0]} {re_content[1]}'
                flag = True
            sql += order_sql
    page, pagesize = param.get('page', 1), param.get('pagesize', 20)
    start = (page-1)*pagesize
    sql += f' limit {pagesize} offset {start}'
    return sql,sql_count


test:案例使用

解析:querycomment函数中,cursor为游标;cursorclass为游标类别:用于获取字典或者数组,pymysql可以通过db.cursorclass.__name__获取,但其他并不一定,故在querycomment的第四个参数cursorclass枚举两个值分别为Cursor、DictCursor。若使用其他连接工具,记得更改哦

from sqlcomment.sql import querycomment
def db_connect():
    db = pymysql.connect(
        host=host,
        port=port,
        user=user,
        passwd=passwd,
        db=database,
        charset='utf8',
        cursorclass = pymysql.cursors.DictCursor
    )
    cursor = db.cursor()
    return db,cursor
param = {'exclude':['url'],
      'condition':['area@notin:("绵竹市","德阳市")','date@>:2023-01-01'],
      'orderby':['date@desc','title@desc'],
      'page':2,
      'pagesize':10
      }
dbname = 'dy'
db,cursor = db_connect()
cursorclass = db.cursorclass.__name__
sql,sql_count = querycomment(param,dbname,cursor,cursorclass)
_,data = cursor.execute(sql),cursor.fetchall()
_,count = cursor.execute(sql_count),cursor.fetchone()


sql,sql_count 返回的是sql语句,需要在返回之后手动执行一次获取数据,这样设计的原因是可能有时候在业务需求上我们还需要对sql语句进一步编写,如联表查询等。其中data是查询回来的数据,count是符合条件的总数据 这样的话有助于前端进行分页操作


whl文件获取


此模块属于抽象部分,故将其打包成whl文件。可直接pip install后使用,安装后也可在lib中查看源码

链接:https://pan.baidu.com/s/1b1rp993bHPyp-J81HUBsxQ

提取码:3u8t

相关文章
|
6天前
|
SQL 运维 监控
SQL查询太慢?实战讲解YashanDB SQL调优思路
本文是Meetup第十期“调优实战专场”的第二篇技术文章,上一篇《高效查询秘诀,解码YashanDB优化器分组查询优化手段》中,我们揭秘了YashanDB分组查询优化秘诀,本文将通过一个案例,助你快速上手YashanDB慢日志功能,精准定位“慢SQL”后进行优化。
|
4天前
|
SQL 索引
【YashanDB知识库】字段加上索引后,SQL查询不到结果
【YashanDB知识库】字段加上索引后,SQL查询不到结果
|
4天前
|
SQL 大数据 数据挖掘
玩转大数据:从零开始掌握SQL查询基础
玩转大数据:从零开始掌握SQL查询基础
72 35
|
23天前
|
SQL 关系型数据库 分布式数据库
利用 PolarDB PG 版向量化引擎,加速复杂 SQL 查询!完成任务领发财新年抱枕!
利用 PolarDB PG 版向量化引擎,加速复杂 SQL 查询!完成任务领发财新年抱枕!
|
15天前
|
SQL 关系型数据库 OLAP
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
30 1
|
1月前
|
人工智能 搜索推荐 测试技术
通义灵码 2.0 智能编码功能评测:Deepseek 加持下的 Python 开发体验
通义灵码 2.0 智能编码功能评测:Deepseek 加持下的 Python 开发体验
98 11
|
22天前
|
SQL 数据可视化 IDE
SQL做数据分析的困境,查询语言无法回答的真相
SQL 在简单数据分析任务中表现良好,但面对复杂需求时显得力不从心。例如,统计新用户第二天的留存率或连续活跃用户的计算,SQL 需要嵌套子查询和复杂关联,代码冗长难懂。Python 虽更灵活,但仍需变通思路,复杂度较高。相比之下,SPL(Structured Process Language)语法简洁、支持有序计算和分组子集保留,具备强大的交互性和调试功能,适合处理复杂的深度数据分析任务。SPL 已开源免费,是数据分析师的更好选择。
|
SQL 存储 索引

热门文章

最新文章