Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从sql查询中提取列名_Python_Mysql_Regex - Fatal编程技术网

Python 如何从sql查询中提取列名

Python 如何从sql查询中提取列名,python,mysql,regex,Python,Mysql,Regex,我只是从这样的查询中提取了列字段 query_split = [query[query.find("select") + len("select"): query.find("from")]] 我有一根这样的绳子 query_split = [' service,count(*) as count,round(sum(mrp),2) as sale '] [' service','count(*) as count','round(sum(mrp),2) as sale'] 我想得到一张

我只是从这样的查询中提取了列字段

query_split = [query[query.find("select") + len("select"): query.find("from")]]
我有一根这样的绳子

 query_split = [' service,count(*) as count,round(sum(mrp),2) as sale ']
[' service','count(*) as count','round(sum(mrp),2) as sale']
我想得到一张这样的清单

 query_split = [' service,count(*) as count,round(sum(mrp),2) as sale ']
[' service','count(*) as count','round(sum(mrp),2) as sale']
这是因为我想得到列名列表

['service','count','sale']
我尝试过其他方法,比如

for file in reader(query_split):
    print(file)
给我输出

[' service', 'count(*) as count', 'round(sum(mrp)', '2) as sale ']
当我接受在查询中使用round(sum,2)类型操作的测试用例时,下面的函数失败了

def get_column_name(query):
    """
    Extracts the column name from a sql query
    :param query: str
    :return: column_name
    list: Column names which that query will fetch
    """
    column_name=[]
    query_split = query[query.find("select") + len("select"): query.find("from")]
    for i in query_split.split(','):

        if "as" in i:
            column_name.append(i.split('as')[-1])
        else:
            column_name.append(i.split(' ')[-1])
    return column_name

您的问题是,这里使用的SQL具有嵌套结构

最干净的解决方案可能是拥有一个理解MySQL方言的SQL解析器。可以说,使用ANTLR最容易做到这一点;如果你好奇的话,你可以找到a和a

要使用正则表达式实现这一点,我们需要在如下匹配模式中使用递归正则表达式来解释平衡括号:

[^,]+(\((?>[^()]++|(?1))*+\))[^,]+|([^(),]+(?:,|$))
说明

  • [^,]+(\((?>[^()]+++\(?1))*+\)[^,]+
    递归正则表达式,用于匹配
    ()
    对以及中间的所有内容(包括逗号),并由与除逗号以外的所有内容匹配的否定字符类四舍五入
  • ([^(),]+(?:,|$)
    匹配常规列

示例代码:

import regex as re
regex = r"[^,]+(\((?>[^()]++|(?1))*+\))[^,]+|([^(),]+(?:,|$))"
test_str = "service,count(*) as count,round(sum(mrp),2) as sale,count(*) as count2,round(sum(mrp),2) as sale2"
matches = re.finditer(regex, test_str, re.MULTILINE)
result = [match.group() for match in matches]
产出:

['service,', 'count(*) as count', 'round(sum(mrp),2) as sale', 'count(*) as count2', 'round(sum(mrp),2) as sale2']

因为我们使用的是PCRE regex特性,所以您需要安装Python的替代包来运行代码。祝你好运。

你是否碰巧执行了你想要解析的查询?如果是这样的话,并且如果您使用符合DBAPI 2的库,光标的位置可能会对您有所帮助。否@shmee,此查询将用于api。据我所知,您正在尝试通过文本处理获取列的名称?假设您没有关于查询的先验信息?您希望进行到什么程度?这是一次性作业还是需要自动化的常规作业?@wp78de它将用于自动化。我已经解决了一个问题,但在这个测试用例中失败。更新了我的问题,说明如何获取简单查询的列名,但在查询中有一些查询操作时失败哇!谢谢你提供了一个很好的解决方案。你能建议我从哪里理解这个正则表达式,以便我以后可以自己使用它们吗。