В этом решении используется метод fromiter от Kieth, но он обрабатывает структуру двумерных таблиц результатов SQL более интуитивно. Кроме того, это улучшает метод Дуга, избегая всех изменений и выравниваний в типах данных Python. Используя структурированный массив , мы можем в значительной степени непосредственно читать результаты MySQL в виде кучи, полностью исключая типы данных Python почти . Я говорю «почти», потому что итератор fetchall по-прежнему создает кортежи Python.
Хотя есть одна оговорка, но это не важная персона. Вы должны знать тип данных ваших столбцов и количество строк заранее.
Знание типов столбцов должно быть очевидным, так как вы знаете, что это за запрос, в противном случае вы всегда можете использовать curs.description и карту констант MySQLdb.FIELD_TYPE. *.
Зная количество строк, вы должны использовать курсор на стороне клиента (который используется по умолчанию). Я не знаю достаточно о внутренностях MySQLdb и клиентских библиотеках MySQL, но, насколько я понимаю, весь результат извлекается из памяти на стороне клиента при использовании курсоров на стороне клиента, хотя я подозреваю, что на самом деле там происходит некоторая буферизация и кэширование. Это будет означать использование двойной памяти для результата, один раз для копии курсора и один раз для копии массива, так что, вероятно, будет хорошей идеей как можно скорее закрыть курсор, чтобы освободить память, если набор результатов большой.
Строго говоря, вам не нужно заранее указывать количество строк, но это означает, что память массива выделяется один раз заранее и не изменяется непрерывно, так как из итератора поступает больше строк, предназначенных для обеспечить огромный прирост производительности.
И с этим, некоторый код
import MySQLdb
import numpy
conn = MySQLdb.connect(host='localhost', user='bob', passwd='mypasswd', db='bigdb')
curs = conn.cursor() #Use a client side cursor so you can access curs.rowcount
numrows = curs.execute("SELECT id, rating FROM video")
#curs.fecthall() is the iterator as per Kieth's answer
#count=numrows means advance allocation
#dtype='i4,i4' means two columns, both 4 byte (32 bit) integers
A = numpy.fromiter(curs.fetchall(), count=numrows, dtype=('i4,i4'))
print A #output entire array
ids = A['f0'] #ids = an array of the first column
#(strictly speaking it's a field not column)
ratings = A['f1'] #ratings is an array of the second colum
Информацию о том, как указывать типы данных и имена столбцов, см. В документации по dtype для dtype и приведенной выше ссылке на структурированные массивы.