Ответ 1
cursor.description даст вам кортеж кортежей, где [0] для каждого является заголовком столбца.
num_fields = len(cursor.description)
field_names = [i[0] for i in cursor.description]
Я не запрашиваю команду 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()
cursor.description даст вам кортеж кортежей, где [0] для каждого является заголовком столбца.
num_fields = len(cursor.description)
field_names = [i[0] for i in cursor.description]
Это то же самое, что и thefreeman, но больше в pythonic образом, используя список и понимание словаря
columns = cursor.description
result = [{columns[index][0]:column for index, column in enumerate(value)} for value in cursor.fetchall()]
pprint.pprint(result)
Подобно @James ответ, более pythonic способ может быть:
fields = map(lambda x:x[0], cursor.description)
result = [dict(zip(fields,row)) for row in cursor.fetchall()]
Вы можете получить один столбец с картой по результату:
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)
)
Я думаю, что это должно делать то, что вам нужно (основывается на ответе выше). Я уверен, что это более питоновский способ написать это, но вы должны получить общую идею.
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)
Вы также можете использовать 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])
для списка имен столбцов (для первой строки) и т.д. Надеюсь, что это поможет!
Похоже, MySQLdb на самом деле не обеспечивает перевод для этого вызова API. Соответствующий вызов API C mysql_fetch_fields
и нет перевода MySQLdb для этого
Это только дополнение к принятому ответу:
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__
Это позволит вам гораздо проще получить доступ к значениям по именам столбцов.
Предположим, у вас есть user
таблица с name
столбца и email
:
cursor.execute('select * from users')
results = get_results(cursor)
for res in results:
print(res.name, res.email)
Пытаться:
cursor.column_names
версия соединителя mysql:
mysql.connector.__version__
'2.2.9'
Вы также можете сделать это, чтобы просто получить названия полей:
table = cursor.description
check = 0
for fields in table:
for name in fields:
if check < 1:
print(name),
check +=1
check =0