Python100个库分享第16个—sqlparse(SQL解析器)

专栏导读

  • 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手

  • 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注

  • 👍 该系列文章专栏:请点击——>Python办公自动化专栏求订阅

  • 🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏求订阅

  • 📕 此外还有python基础专栏:请点击——>Python基础学习专栏求订阅

  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏

  • ❤️ 欢迎各位佬关注! ❤️

库的介绍

  • 来自文心一言

sqlparse 是一个 Python 库,用于解析 SQL 语句。它可以帮助你以编程方式处理和分析 SQL 语句的结构。 具体来说,sqlparse 提供了以下功能:

1、解析 SQL 语句:它将 SQL 语句分解为多个部分,如 SELECT、FROM、WHERE 等,使你可以单独访问或修改这些部分。

2、格式化 SQL 语句:你可以使用 sqlparse 来重新格式化 SQL 语句,使其更易于阅读或符合特定的格式要求。 获取 SQL 语句的详细信息:通过 sqlparse,你可以获取关于 SQL 语句的详细信息,如它包含哪些关键字、标识符、字符串等。

3、分割 SQL 语句:如果你有一个包含多个 SQL 语句的字符串,sqlparse 可以帮助你将其分割为单独的 SQL 语句。

库的安装

pip install sqlparse -i https://pypi.tuna.tsinghua.edu.cn/simple/

1、解析 SQL 语句

import sqlparse

# 假设有一个 SQL 查询字符串
sql_query = "SELECT * FROM users WHERE id = 1;"

# 解析 SQL 语句
parsed = sqlparse.parse(sql_query)

# parsed 是一个 StatementList 对象,包含多个 SQLStatement 对象
first_statement = parsed[0]

# 打印解析后的第一个语句
print(first_statement.tokens)
  • 输出

[<DML 'SELECT' at 0x25F5D69EA40>, <Whitespace ' ' at 0x25F5D69EAA0>, <Wildcard '*' at 0x25F5D69EB00>, <Whitespace ' ' at 0x25F5D69EB60>, <Keyword 'FROM' at 0x25F5D69EBC0>, <Whitespace ' ' at 0x25F5D69EC20>, <Identifier 'users' at 0x25F5D67ED50>, <Whitespace ' ' at 0x25F5D69ECE0>, <Where 'WHERE ...' at 0x25F5D67EC50>]

2、格式化 SQL 语句

import sqlparse
sql_query = "SELECT * FROM users WHERE id = 1;"

# 使用 format 方法美化 SQL 语句
formatted_sql = sqlparse.format(sql_query, reindent=True, keyword_case='upper')

print(formatted_sql)  # 输出: "SELECT * FROM users WHERE id = 1;"
  • 输出

SELECT *
FROM users
WHERE id = 1;

3、提取表名

import sqlparse

# 假设有一个 SQL 查询字符串
sql_query = '''
            SELECT * FROM users WHERE id = 1;
            SELECT * FROM customers  WHERE age > 30;
            '''
# 解析 SQL 语句
parsed = sqlparse.parse(sql_query)

# 解析并遍历 token 以找到表名
for stmt in parsed:
    for token in stmt.tokens:
        if isinstance(token, sqlparse.sql.Identifier):
            table_name = token.get_real_name()
            print(table_name)

  • 输出

users
customers

4、分割多条 SQL 语句

import sqlparse

# 假设有一个 SQL 查询字符串
multi_query = ('''
                SELECT * FROM users; SELECT * FROM orders;
                SELECT * FROM users WHERE id = 1;
                SELECT * FROM customers  WHERE age > 30;

               '''
               )

# 将多条 SQL 语句分割开
statements = sqlparse.split(multi_query)

for statement in statements:
    print(statement)

  • 输出

SELECT * FROM users;
SELECT * FROM orders;
SELECT * FROM users WHERE id = 1;
SELECT * FROM customers  WHERE age > 30;

实际应用代码

import sqlparse
import re


def format_sql(sql_content):
    '''将sql语句进行规范化,并去除sql中的注释,输入和输出均为字符串'''
    parse_str = sqlparse.format(sql_content, reindent=True, strip_comments=True)
    return parse_str


def extract_temp_tables(with_clause):
    '''从WITH子句中提取临时表名,输出为列表'''
    temp_tables = re.findall(r'\b(\w+)\s*as\s*\(', with_clause, re.IGNORECASE)
    return temp_tables


def extract_table_names_from_sql(sql_query):
    '''从sql中提取对应的表名称,输出为列表'''
    table_names = set()
    # 解析SQL语句
    parsed = sqlparse.parse(sql_query)
    # 正则表达式模式,用于匹配表名
    table_name_pattern = r'\bFROM\s+([^\s\(\)\,]+)|\bJOIN\s+([^\s\(\)\,]+)'

    # 用于存储WITH子句中的临时表名
    remove_with_name = []

    # 遍历解析后的语句块
    for statement in parsed:
        # 转换为字符串
        statement_str = str(statement).lower()

        # 将字符串中的特殊语法置空
        statement_str = re.sub(r'(substring|extract)\s*\(((.|\s)*?)\)', '', statement_str)

        # 查找匹配的表名
        matches = re.findall(table_name_pattern, statement_str, re.IGNORECASE)

        for match in matches:
            # 提取非空的表名部分
            for name in match:
                if name:
                    # 对于可能包含命名空间的情况,只保留最后一部分作为表名
                    table_name = name.split('.')[-1]
                    # 去除表名中的特殊符号
                    table_name = re.sub(r'("|`|\'|;)', '', table_name)
                    table_names.add(table_name)

        # 处理特殊的WITH语句
        if 'with' in statement_str:
            remove_with_name = extract_temp_tables(statement_str)

    # 移除多余的表名
    if remove_with_name:
        table_names = list(set(table_names) - set(remove_with_name))

    return table_names


sql_query = '''
WITH
  -- 定义第一个公共表表达式
  SalesTeam AS (
    SELECT
      SalespersonID,
      SUM(TotalSales) AS TotalSales
    FROM
      Sales
    GROUP BY
      SalespersonID
  ),

  -- 定义第二个公共表表达式
  TopPerformers AS (
    SELECT
      SalespersonID
    FROM
      SalesTeam
    WHERE
      TotalSales > 100000
  )

-- 主查询,使用两个公共表表达式进行多表联合查询
SELECT
  E.EmployeeID,
  E.EmployeeName,
  ST.TotalSales
FROM
  Employees E
JOIN
  SalesTeam ST ON E.EmployeeID = ST.SalespersonID
JOIN
  TopPerformers TP ON E.EmployeeID = TP.SalespersonID;
'''

parse_str = format_sql(sql_query)
table_names = extract_table_names_from_sql(parse_str)
# 打印提取的表名
print(table_names)


参考:

1、通义千问
2、如何利用python来提取SQL语句中的表名称

总结

  • 希望对初学者有帮助

  • 致力于办公自动化的小小程序员一枚

  • 希望能得到大家的【一个免费关注】!感谢

  • 求个 🤞 关注 🤞

  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏

  • 求个 ❤️ 喜欢 ❤️

  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏

  • 求个 👍 收藏 👍

  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一晌小贪欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值