0

我正在尝试使用 sqlparse 提取查询中的所有表名,但我遇到了用括号括起来的子查询或插入语句的问题。

我有以下查询,

import sqlparse 
    
sql = """ 
          create test.test_table as (
                            select 1
                            from fake.table
                        );
        """
    

当我查找在括号中包含语句的标记时,使用

y = sqlparse.parse(sql)

for i in y[0].tokens:
    if isinstance(i, Identifier):
        print(i)
        print(i.get_real_name())

我得到以下结果,

test.test_table as (
                            select 1
                            from fake.table
                        )
test_table

结果仅作为一个标识符令牌返回。当我尝试从括号内获取表名时,所有返回的是 test.test_table。我最终要做的是提取两个表名 test.test_table 和 fake.table

有没有人对我如何去做这件事有任何见解?

4

1 回答 1

1

这可能会有所帮助,我一直在使用其中包含子查询的 Select SQL 语句,因此通常格式为:

Select blah from (select blah from table_name) alias

所以首先我忽略第一个 Select 语句,并查找包含单词 Select 的标记:

for item in parsed.tokens:

    if 'SELECT' in identifier.value.upper():
        subquery = identifier.value

子查询将返回

(从 table_name 中选择 blah)别名

然后我有一个单独的函数,它删除最外面的括号和别名,只给出子查询脚本:

def subquery_parsing(subquery, full_tables, tables, alias):
    #print(subquery)
    #new subquery string ready to parse
    res_sub = """"""

    #captures the alias outside the parantheses
    alias = """"""
    
    #record the number of parentheses as they open and close
    paren_cnt = 0


    for char in subquery:
        #if ( and there's already been a ( , include it
        if char == '(' and paren_cnt > 0:
            res_sub += char
    
        #if (, add to the count
        if char == '(':
            paren_cnt += 1
   
        # if ) and there's at least 2 (, include it
        if char == ')' and paren_cnt > 1:
            res_sub += char
          
        # if ), subtract from the count        
        if char == ')':
            paren_cnt -= 1
    
        # capture the script
        if char != '(' and char != ')' and paren_cnt >0:
            res_sub += char
    
        # capture the alias
        if char != '(' and char != ')'  and char != ' ' and paren_cnt == 0:
            alias += char

这返回

从 table_name 中选择 blah

然后您应该能够再次运行 sqlparse.parse 并获取表名。

于 2021-05-26T12:29:47.350 回答