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

120 投票
13 回答
218911 浏览
提问于 2025-04-16 11:53

我不是在问 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()      

13 个回答

35

和@James的回答类似,这里有一种更符合Python风格的方法:

fields = [field_md[0] for field_md in cursor.description]
result = [dict(zip(fields,row)) for row in cursor.fetchall()]

你可以通过列表推导式来获取结果中的单独一列:

extensions = [row['ext'] for row in result)

或者在列表推导式中加一个if来过滤结果:

large = [row for row in result if row['filesize'] > 1024 and row['filesize'] < 4096]

还可以对过滤后的列进行值的累加:

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

这和thefreeman的回答是一样的,不过用了一种更符合Python风格的方法,使用了列表和字典的推导式。

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

pprint.pprint(result)
292

cursor.description 会给你一个包含多个元组的元组,其中每个元组的第一个元素就是列的标题。

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

撰写回答