【问题标题】:Parsing SQL file with Python用 Python 解析 SQL 文件
【发布时间】:2022-01-19 18:07:22
【问题描述】:

我正在尝试解析 SQL 代码并从中提取所有表名。

sql代码中的表名有时写成别名或者schema.table或者只写表名。

我正在使用 sqlparse 包,但我只获取表的别名,您会在下面找到我的代码:

SELECT  *
FROM VA_ASSISTES va, datamart_Sales.dbo.Seller f,
datamart_Sales.dbo.ARTICLES a, SITE s, datamart_Sales.dbo.TEMPS t

这是我现在得到的结果,只有别名:

表格:va、f、a、s、t

但是,我想像这样检索表名: datamart_Sales.dbo.Seller、datamart_Sales.dbo.ARTICLES、datamart_Sales.dbo.TEMPS、网站

如果有人能帮我提取上述所有情况下的表名,我将不胜感激。

【问题讨论】:

    标签: python sql


    【解决方案1】:

    sqlparse 没有将identifiers 明确标记为属于列名/别名或表名/别名。因此,当出现from 关键字时,您将不得不遍历已解析的标记并标记,然后保留后续的identifiers

    import sqlparse
    s = """SELECT  *
    FROM VA_ASSISTES va, datamart_Sales.dbo.Seller f,
    datamart_Sales.dbo.ARTICLES a, SITE s, datamart_Sales.dbo.TEMPS t"""
    s1="""SELECT job_id,AVG(salary) FROM VA_ASSISTES va, datamart_Sales.dbo.Seller f, datamart_Sales.dbo.ARTICLES a, SITE s, datamart_Sales.dbo.TEMPS t Havning job_id,AVG(salary)< (SELECT MAX(AVG(min_salary)) FROM jobs WHERE job_id IN (SELECT job_id FROM job_history WHERE department_id BETWEEN 50 AND 100) GROUP BY job_id));"""
    def get_tables(p):
       f = False
       for i in p:
          if i.value.lower() == 'from':
             f = True
          if f and isinstance(i, (sqlparse.sql.Identifier, sqlparse.sql.IdentifierList)):
             if isinstance(i, sqlparse.sql.IdentifierList):
                yield from [j.value.split() for j in i.get_identifiers()]
             else:
                 yield i.value.split()
             f = False
          yield from get_tables(getattr(i, '__iter__', lambda :[])())
    
    print(list(get_tables(sqlparse.parse(s)[0])))
    print(list(get_tables(sqlparse.parse(s1)[0])))
    

    输出:

    [['VA_ASSISTES', 'va'], ['datamart_Sales.dbo.Seller', 'f'], ['datamart_Sales.dbo.ARTICLES', 'a'], ['SITE', 's'], ['datamart_Sales.dbo.TEMPS', 't']]
    [['VA_ASSISTES', 'va'], ['datamart_Sales.dbo.Seller', 'f'], ['datamart_Sales.dbo.ARTICLES', 'a'], ['SITE', 's'], ['datamart_Sales.dbo.TEMPS', 't'], ['jobs'], ['job_history']]
    

    【讨论】:

    • 感谢您的及时回复!如果我有这样的嵌套查询怎么样: SELECT job_id,AVG(salary) FROM VA_ASSISTES va, datamart_Sales.dbo.Seller f, datamart_Sales.dbo.ARTICLES a, SITE s, datamart_Sales.dbo.TEMPS t Havning job_id,AVG(salary )
    • @Abdelhak 您将需要使用递归。请查看我最近的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    相关资源
    最近更新 更多