【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

相关文章
|
1月前
|
数据采集 小程序 API
Python实现isbn查询书籍详细信息
Python实现通过isbn码查询书籍详细信息
24 0
|
2月前
|
Shell Linux Python
【Python】一键查询依赖生成文件 requirements.txt
【Python】一键查询依赖生成文件 requirements.txt
33 0
|
2月前
|
JSON 前端开发 数据格式
12306火车票查询--Python可以这么玩!!!
12306火车票查询--Python可以这么玩!!!
|
2月前
|
数据采集 Python
利用Python通过商品条形码查询商品信息
利用Python通过商品条形码查询商品信息
51 0
|
3月前
|
SQL Java 数据库连接
Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?
Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?
39 0
|
3月前
|
数据挖掘 Go 索引
Python 使用pandas 进行查询和统计详解
Python 使用pandas 进行查询和统计详解
38 0
|
3月前
|
JSON 关系型数据库 MySQL
Python MySQL操作实战教程(1):查询并数据JSON格式
Python MySQL操作实战教程(1):查询并数据JSON格式
332 0
|
5月前
|
Python
查询python的安装路径
查询python的安装路径
|
5月前
|
网络安全 Python
开源python脚本系列-批量查询ssl过期时间
开源python脚本系列-批量查询ssl过期时间
推荐文章
更多