Python sqlalchemy получает имена столбцов динамически?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
connection = create_engine('mysql://user:[email protected]:3306/db').connect()
result = connection.execute("select * from table")
for v in result:
print v['id']
print v['name']
connection.close()
Как я могу динамически использовать имена столбцов COLUMNS? в этом случае id
и name
Ответы
Ответ 1
Вы можете найти столбцы, вызвав result.keys()
, или вы можете получить к ним доступ, вызвав v.keys()
внутри цикла for
.
Здесь пример с использованием items()
:
for v in result:
for column, value in v.items():
print('{0}: {1}'.format(column, value))
Ответ 2
что-то вроде этого
headers=[ i[0] for i in result.cursor.description ]
тот же вопрос здесь вернуть имена столбцов из инструкции pyodbc execute()
Ответ 3
Самое прямое решение
Не может быть проще, чем однострочное решение, использующее понимание списка. Это и есть самый прямой метод:
[col for col in result.keys()]
# return: ['id', 'name']
Ответ @Saul также работает, но вам нужно быть осторожным, перебирая только первый элемент для каждого cursor.description
, чтобы вы не получили кучу None
в каждом кортеже возвращенного списка.
Это также менее эффективно, потому что вам нужно ResultProxy
, получить доступ к cursor.description
и для каждого из них получить элемент только с индексом 0.
Использование timeit
в Python с 500 000 итераций показало разницу в скорости (0,016 против 0,011):
connection = create_engine('sqlite:///rcsample.db').connect()
result = connection.execute("select * from response")
def cursfunc():
return [ i[0] for i in result.cursor.description ]
print(timeit.timeit("cursfunc()", setup="from __main__ import cursfunc", number=500000))
# return: 0.01606178
Хотя предлагаемое решение завершается за ~ 30% меньше времени:
connection = create_engine('sqlite:///rcsample.db').connect()
result = connection.execute("select * from response")
def keysfunc():
return [col for col in result.keys()]
print(timeit.timeit("keysfunc()", setup="from __main__ import cursfunc", number=500000))
# return: 0.01097001
На самом деле, я подозреваю, что разница во времени в таблице с большим количеством столбцов может быть больше, чем в явно упрощенном примере выше.
На практике: ключи и ценности
На практике вы, вероятно, захотите распечатать ключ и значения динамически. Есть два способа сделать это. Первый:
results = conn.execute('SELECT * FROM salesperson')
[{column:value for column, value in result.items()} for result in results]
# returns: [{'id': 1, 'name': 'John Doe'}, {'id': 2, 'name':
# 'Margaret'}, {'id': 3, 'name': 'Anna'}]
Альтернативно используя распаковку:
rows = conn.execute('SELECT * FROM salesperson LIMIT 2').fetchall()
print([{**row} for row in rows])
# returns: [{'id': 1, 'name': 'John Doe'}, {'id': 2, 'name': 'Margaret'}]
Оба эти метода являются прямыми и питоническими, но также освобождают программиста от необходимости явно указывать (или знать заранее) имена столбцов.