Получить список значений полей из Python sqlite3, а не кортежей, представляющих строки
Это раздражает то, как Python sqlite3
модуль всегда возвращает список кортежей! Когда я запрашиваю один столбец, я бы предпочел получить простой список.
например. когда я выполняю
SELECT somecol FROM sometable
и вызовите
cursor.fetchall()
он возвращает
[(u'one',), (u'two',), (u'three',)]
но я бы предпочел просто
[u'one', u'two', u'three']
Есть ли способ сделать это?
Ответы
Ответ 1
Вы действительно не хотите этого делать - все, что вы делаете в соответствии с использованием zip или пониманием списка, - это просто циклы процессора и сосать память, не добавляя значительного значения. Вы гораздо лучше обслуживаете только кортежи.
Что касается того, почему он возвращает кортежи, это потому, что для Python DBD API 2.0 требуется от fetchall
.
Ответ 2
sqlite3.Connection
имеет атрибут row_factory
.
В документации указано, что:
Вы можете изменить этот атрибут на вызываемый, который принимает курсор и исходную строку как кортеж и вернет строку реального результата. Таким образом, вы можете реализовать более сложные способы возврата результатов, например, вернуть объект, который также может обращаться к столбцам по имени.
Чтобы вернуть список одиночных значений из SELECT
, например, id
, вы можете назначить лямбда row_factory
, которая возвращает первое индексированное значение в каждой строке; например:
import sqlite3 as db
conn = db.connect('my.db')
conn.row_factory = lambda cursor, row: row[0]
c = conn.cursor()
ids = c.execute('SELECT id FROM users').fetchall()
Это дает что-то вроде:
[1, 2, 3, 4, 5, 6] # etc.
Ответ 3
data=cursor.fetchall()
COLUMN = 0
column=[elt[COLUMN] for elt in data]
(Мое предыдущее предложение column=zip(*data)[COLUMN]
вызывает IndexError
, если data
- пустой кортеж. Напротив, приведенное выше описание списка просто создает пустой список. В зависимости от вашей ситуации повышение IndexError
может предпочтительнее, но я оставлю это вам решать.)
Ответ 4
Я использую модуль pandas для работы с табличным содержимым:
df = pd.DataFrame(cursor.fetchall(), columns=['one','two'])
Список значений для столбца "один" просто обозначается как:
df['one'].values
Вы даже можете использовать собственный индекс для привязки данных:
df0 = pd.DataFrame.from_records(cursor.fetchall(), columns=['Time','Serie1','Serie2'],index='Time')
Ответ 5
zlist = []
tupls = c.fetchall()
for tup in tupls:
t = str(tup).replace("('","").replace("',)","")
zlist.append(t)
Теперь вам не нужно иметь дело с кортежами, пандами или чем-то из вышеперечисленного, которое не сработало.
Ответ 6
укажите случай, когда cursor.fetchall() возвращает пустой список:
try:
columnlist = list(zip(*cursor.fetchall())[COLUMN_INDEX])
except IndexError:
columnlist = []