pan*_*ish 58 python mysql mysql-python
我不是要求SHOW COLUMNS命令.
我想创建一个与heidisql类似的应用程序,您可以在其中指定SQL查询,并在执行时返回包含表示查询结果的行和列的结果集.结果集中的列名称应与SQL查询中定义的所选列相匹配.
在我的Python程序(使用MySQLdb)中,我的查询只返回行和列结果,但不返回列名.在下面的例子中,列名应为ext,totalsize和filecount.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()
Run Code Online (Sandbox Code Playgroud)
use*_*477 201
cursor.description将为您提供一个元组元组,其中每个元组的[0]是列标题.
num_fields = len(cursor.description)
field_names = [i[0] for i in cursor.description]
Run Code Online (Sandbox Code Playgroud)
Jam*_*mes 26
这与自由人相同,但更多的是使用列表和字典理解的pythonic方式
columns = cursor.description
result = [{columns[index][0]:column for index, column in enumerate(value)} for value in cursor.fetchall()]
pprint.pprint(result)
Run Code Online (Sandbox Code Playgroud)
jua*_*ant 12
与@James的答案类似,更为pythonic的方式可以是:
fields = map(lambda x:x[0], cursor.description)
result = [dict(zip(fields,row)) for row in cursor.fetchall()]
Run Code Online (Sandbox Code Playgroud)
您可以在结果上获得包含地图的单个列:
extensions = map(lambda x: x['ext'], result)
Run Code Online (Sandbox Code Playgroud)
或过滤结果:
filter(lambda x: x['filesize'] > 1024 and x['filesize'] < 4096, result)
Run Code Online (Sandbox Code Playgroud)
或累积过滤列的值:
totalTxtSize = reduce(
lambda x,y: x+y,
filter(lambda x: x['ext'].lower() == 'txt', result)
)
Run Code Online (Sandbox Code Playgroud)
我认为这应该做你需要的(建立在上面的答案).我确信这是一种更加灵巧的方式来编写它,但你应该得到一般的想法.
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)
Run Code Online (Sandbox Code Playgroud)
您也可以使用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()
Run Code Online (Sandbox Code Playgroud)
标准字典功能适用于例如len(row[0])计算第一行的列数,列list(row[0])名列表(第一行)等。希望这对您有所帮助!
这只是已接受答案的附加内容:
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
Run Code Online (Sandbox Code Playgroud)
在哪里dotdict:
class dotdict(dict):
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
Run Code Online (Sandbox Code Playgroud)
这将使您可以更轻松地按列名称访问值。
假设您有一个user包含列name和的表email:
cursor.execute('select * from users')
results = get_results(cursor)
for res in results:
print(res.name, res.email)
Run Code Online (Sandbox Code Playgroud)
与建议的解决方案类似,只是结果是 json 和column_header : vaulefor db_queryie sql。
cur = conn.cursor()
cur.execute(sql)
res = [dict((cur.description[i][0], value) for i, value in enumerate(row)) for row in cur.fetchall()]
Run Code Online (Sandbox Code Playgroud)
输出json示例:
[
{
"FIRST_ROW":"Test 11",
"SECOND_ROW":"Test 12",
"THIRD_ROW":"Test 13"
},
{
"FIRST_ROW":"Test 21",
"SECOND_ROW":"Test 22",
"THIRD_ROW":"Test 23"
}
]
Run Code Online (Sandbox Code Playgroud)