栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

peewee将log转可执行SQL

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

peewee将log转可执行SQL

文章目录
  • 问题描述
  • 解决方案
    • 替换元组参数
    • 字符串解析
  • 参考文献

问题描述

调用 baseQuery.sql() 可以获得一个二元组,包含 SQL 和参数,将这个二元组转成可执行 SQL

peewee 版本

pip install peewee==3.14.4

示例

import datetime
from peewee import *

db = SqliteDatabase('test')


class Product(Model):
    id = PrimaryKeyField()
    name = CharField()
    type = CharField()
    create_at = DateTimeField(null=True)

    class meta:
        database = db


db.connect()
db.create_tables([Product])
data = [
    Product(name='apple', type='fruit', create_at=datetime.datetime(2021, 1, 1)),
    Product(name='banana', type='fruit', create_at=datetime.datetime(2021, 1, 2)),
    Product(name='cat', type='animal', create_at=None),
    Product(name='dog', type='animal', create_at=datetime.datetime.now()),
]
Product.bulk_create(data)

lastest = Product.select(
    Product.id, fn.MAX(Product.create_at).alias('create_at')
).group_by(Product.type).alias('lastest')

query = Product.select().join(
    lastest, on=((Product.id == lastest.c.id) & (Product.create_at == lastest.c.create_at))
).where(
    (Product.create_at > datetime.datetime(2021, 1, 1) &
     Product.create_at.is_null(False) &
     Product.create_at != datetime.datetime.min)
)
print(query.sql())
# ('SELECT "t1"."id", "t1"."name", "t1"."type", "t1"."create_at" FROM "product" AS "t1" INNER JOIN (SELECt "t1"."id", MAX("t1"."create_at") AS "create_at" FROM "product" AS "t1" GROUP BY "t1"."type") AS "lastest" ON (("t1"."id" = "lastest"."id") AND ("t1"."create_at" = "lastest"."create_at")) WHERe (((? AND ("t1"."create_at" IS NOT ?)) AND "t1"."create_at") != ?)', [datetime.datetime(2021, 1, 1, 0, 0), None, datetime.datetime(1, 1, 1, 0, 0)])




解决方案 替换元组参数

代码

import re
import datetime  # eval()时含有datetime类型,不能去掉


def log2sql(log):
    """日志转SQL"""
    datetime_pattern = "(d{4}-d{1,2}-d{1,2}sd{1,2}:d{1,2}:d{1,2})"  # 时间字符串正则表达式
    datetime_repl = lambda x: '"{}"'.format(x.group())
    result = []
    for s in log.strip().split("n"):
        sql, parameters = eval(s)
        for parameter in parameters:
            sql = sql.replace("?", str(parameter), 1)
        sql = sql.replace("None", "NULL")
        sql = re.sub(pattern=datetime_pattern, repl=datetime_repl, string=sql)  # 给时间字符串加上双引号
        result.append(sql)
    return result


if __name__ == '__main__':
    log = """
('SELECT "t1"."id", MAX("t1"."create_at") AS "create_at" FROM "product" AS "t1" GROUP BY "t1"."type"', [])
('SELECt "t1"."id", "t1"."name", "t1"."type", "t1"."create_at" FROM "product" AS "t1" INNER JOIN (SELECt "t1"."id", MAX("t1"."create_at") AS "create_at" FROM "product" AS "t1" GROUP BY "t1"."type") AS "lastest" ON (("t1"."id" = "lastest"."id") AND ("t1"."create_at" = "lastest"."create_at")) WHERe (((? AND ("t1"."create_at" IS NOT ?)) AND "t1"."create_at") != ?)', [datetime.datetime(2021, 1, 1, 0, 0), None, datetime.datetime(1, 1, 1, 0, 0)])
"""
    result = log2sql(log)
    for sql in result:
        print(sql)
    print('共{}条'.format(len(result)))
# SELECt "t1"."id", MAX("t1"."create_at") AS "create_at" FROM "product" AS "t1" GROUP BY "t1"."type"
# SELECt "t1"."id", "t1"."name", "t1"."type", "t1"."create_at" FROM "product" AS "t1" INNER JOIN (SELECt "t1"."id", MAX("t1"."create_at") AS "create_at" FROM "product" AS "t1" GROUP BY "t1"."type") AS "lastest" ON (("t1"."id" = "lastest"."id") AND ("t1"."create_at" = "lastest"."create_at")) WHERe ((("2021-01-01 00:00:00" AND ("t1"."create_at" IS NOT NULL)) AND "t1"."create_at") != "0001-01-01 00:00:00")
# 共2条



字符串解析

代码

 




参考文献
  1. Python ORM框架peewee
  2. peewee API documentation
  3. Python正则表达式提取datetime日期+时间
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/269778.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号