Python sqlalchemy получить имена столбцов динамически? - PullRequest
10 голосов
/ 21 января 2012
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sqlalchemy import create_engine

connection = create_engine('mysql://user:passwd@localhost:3306/db').connect()

result = connection.execute("select * from table")
for v in result:
        print v['id']
        print v['name']
connection.close()

как я могу динамически получить НАЗВАНИЯ СТОЛБНЫХ КОЛОНН? в этом случае id и name

Ответы [ 3 ]

14 голосов
/ 21 января 2012

Вы можете найти столбцы, вызвав result.keys(), или получить к ним доступ, вызвав v.keys() внутри цикла for.

Вот пример использования items():

for v in result:
    for column, value in v.items():
        print('{0}: {1}'.format(column, value))
3 голосов
/ 12 мая 2019

Самое прямое решение

Не может быть проще, чем однострочное решение, использующее понимание списка. Это и есть самый прямой метод:

[col for col in result.keys()]
# return: ['id', 'name']

@ Ответ Саула также работает, но вам нужно быть осторожным при переборе только первого элемента через каждый 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'}]

Оба эти метода являются прямыми и питоническими, но также освобождают программиста от необходимости явно указывать (или знать заранее) имена столбцов.

2 голосов
/ 11 августа 2017

что-то вроде этого

headers=[ i[0] for i in result.cursor.description ]

тот же вопрос здесь возвращает имена столбцов из инструкции pyodbc execute ()

...