首页 文章

MySQL:从查询中获取列名或别名

提问于
浏览
46

我不是要求 SHOW COLUMNS 命令 .

我想创建一个与heidisql类似的应用程序,您可以在其中指定SQL查询,并在执行时返回包含表示查询结果的行和列的结果集 . 结果集中的列名称应与SQL查询中定义的所选列相匹配 .

在我的Python程序中(使用 MySQLdb ),我的查询只返回行和列结果,但不返回列名 . 在以下示例中,列名称为 exttotalsizefilecount . SQL最终将从程序外部 .

我能想到的唯一方法就是编写自己的SQL解析器逻辑来提取选定的列名 .

有没有一种简单的方法来获取提供的SQL的列名?接下来我需要知道查询返回了多少列?

# Python

import MySQLdb

#===================================================================
# connect to mysql
#===================================================================

try:
    db = MySQLdb.connect(host="myhost", user="myuser", passwd="mypass",db="mydb")
except MySQLdb.Error, e:
    print "Error %d: %s" % (e.args[0], e.args[1])
    sys.exit (1)

#===================================================================
# query select from table
#===================================================================

cursor = db.cursor ()   

cursor.execute ("""\
     select ext,
        sum(size) as totalsize,
        count(*) as filecount
     from fileindex
    group by ext
    order by totalsize desc;
""")

while (1):
    row = cursor.fetchone ()
    if row == None:
        break
    print "%s %s %s\n" % (row[0], row[1], row[2])

cursor.close()
db.close()

7 回答

  • 0

    cursor.description将为您提供一个元组元组,其中每个元组的[0]是列 Headers .

    num_fields = len(cursor.description)
    field_names = [i[0] for i in cursor.description]
    
  • 4

    这与自由人相同,但更多是以pythonic方式使用列表和字典理解

    columns = cursor.description 
    result = [{columns[index][0]:column for index, column in enumerate(value)} for value in cursor.fetchall()]
    
    pprint.pprint(result)
    
  • 179

    与@James的答案类似,更加pythonic的方式可以是:

    fields = map(lambda x:x[0], cursor.description)
    result = [dict(zip(fields,row))   for row in cursor.fetchall()]
    

    您可以在结果上获得包含 Map 的单个列:

    extensions = map(lambda x: x['ext'], result)
    

    或过滤结果:

    filter(lambda x: x['filesize'] > 1024 and x['filesize'] < 4096, result)
    

    或累积过滤列的值:

    totalTxtSize = reduce(
            lambda x,y: x+y,
            filter(lambda x: x['ext'].lower() == 'txt', result)
    )
    
  • 22

    我认为这应该做你需要的( Build 在上面的答案) . 我确信这是一种更加灵巧的方式来编写它,但你应该得到一般的想法 .

    cursor.execute(query)
    columns = cursor.description
    result = []
    for value in cursor.fetchall():
        tmp = {}
        for (index,column) in enumerate(value):
            tmp[columns[index][0]] = column
        result.append(tmp)
    pprint.pprint(result)
    
  • 10

    你也可以使用 MySQLdb.cursors.DictCursor . 这会将您的结果集转换为python词典的python列表,尽管它使用特殊的游标,因此在技术上不如接受的答案便携 . 关于速度不确定 . 这是使用它的编辑过的原始代码 .

    #!/usr/bin/python -u
    
    import MySQLdb
    import MySQLdb.cursors
    
    #===================================================================
    # connect to mysql
    #===================================================================
    
    try:
        db = MySQLdb.connect(host='myhost', user='myuser', passwd='mypass', db='mydb', cursorclass=MySQLdb.cursors.DictCursor)
    except MySQLdb.Error, e:
        print 'Error %d: %s' % (e.args[0], e.args[1])
        sys.exit(1)
    
    #===================================================================
    # query select from table
    #===================================================================
    
    cursor = db.cursor()
    
    sql = 'SELECT ext, SUM(size) AS totalsize, COUNT(*) AS filecount FROM fileindex GROUP BY ext ORDER BY totalsize DESC;'
    
    cursor.execute(sql)
    all_rows = cursor.fetchall()
    
    print len(all_rows) # How many rows are returned.
    for row in all_rows: # While loops always make me shudder!
        print '%s %s %s\n' % (row['ext'], row['totalsize'], row['filecount'])
    
    cursor.close()
    db.close()
    

    例如,标准字典函数适用于 len(row[0]) 来计算第一行的列数, list(row[0]) 用于列名列表(第一行)等 . 希望这会有所帮助!

  • 7

    看起来MySQLdb实际上并没有为该API调用提供翻译 . 相关的C API调用是mysql_fetch_fieldsthere is no MySQLdb translation for that

  • 2

    这只是接受答案的附加内容:

    def get_results(db_cursor):
        desc = [d[0] for d in db_cursor.description]
        results = [dotdict(dict(zip(desc, res))) for res in db_cursor.fetchall()]
        return results
    

    其中 dotdict 是:

    class dotdict(dict):
        __getattr__ = dict.get
        __setattr__ = dict.__setitem__
        __delattr__ = dict.__delitem__
    

    这将允许您通过列名更轻松地访问值 .
    假设您有一个包含 nameemail 列的 user 表:

    cursor.execute('select * from users')
    results = get_results(cursor)
    for res in results:
      print(res.name, res.email)
    

相关问题