указатель.fetchall () vs list (курсор) в Python
оба метода возвращают список возвращенных деталей запроса, я что-то пропустила?
или у них действительно одинаковые обычаи?
любой производительности-мудрый различия?
4 ответов
если вы используете курсор по умолчанию, а MySQLdb.cursors.Cursor
, весь результирующий набор будет храниться на стороне клиента (т. е. в списке Python) к моменту cursor.execute()
завершено.
поэтому, даже если вы используете
for row in cursor:
вы не получите никакого сокращения объема памяти. Весь результирующий набор уже сохранен в списке (см. self._rows
in MySQLdb/cursors.py).
однако, если вы используете SSCursor или SSDictCursor:
import MySQLdb
import MySQLdb.cursors as cursors
conn = MySQLdb.connect(..., cursorclass=cursors.SSCursor)
затем результирующий набор хранится на сервере, mysqld. Теперь вы можете написать
cursor = conn.cursor()
cursor.execute('SELECT * FROM HUGETABLE')
for row in cursor:
print(row)
и строки будут извлекаться один за другим с сервера, таким образом, не требуя, чтобы Python сначала построил огромный список кортежей и, таким образом, сохранил память.
в противном случае, как уже говорилось, cursor.fetchall()
и list(cursor)
по существу то же самое.
cursor.fetchall()
и list(cursor)
по существу то же самое. Другой вариант-не извлекать список, а вместо этого просто зацикливаться на голом объекте курсора:
for result in cursor:
Это может быть более эффективным, если результирующий набор Большой, так как он не должен извлекать весь результирующий набор и хранить его в памяти; он может просто постепенно получить каждый элемент (или пакетировать их в меньших партиях).
a (MySQLdb/pymysql-specific) разница стоит отметить при использовании DictCursor
Это list(cursor)
всегда будет давать вам список, в то время как cursor.fetchall()
дает вам список если результирующий набор пуст, в этом случае он дает вам пустой кортеж. Это было так в MySQLdb и остается таковым в более новом PyMySQL, где он не будет исправлено для обратной совместимости. Пока это не является нарушением API базы данных Python Спецификация, это все еще удивительно и может легко привести к ошибке типа, вызванной неправильным предположением, что результатом является список, а не последовательность.
учитывая вышесказанное, я предлагаю всегда благосклонно list(cursor)
над cursor.fetchall()
, чтобы избежать когда-либо попасться на загадочную ошибку типа в крайнем случае, когда ваш результирующий набор пуст.
list(cursor)
работает, потому что курсор-это итерируемый; вы также можете использовать cursor
в цикле:
for row in cursor:
# ...
хорошая реализация адаптера базы данных будет получать строки партиями с сервера, экономя на требуемом объеме памяти, поскольку ему не нужно будет удерживать полное результирующий набор, в памяти. cursor.fetchall()
и вместо того, чтобы вернуть полный список.
мало смысла в использовании list(cursor)
над cursor.fetchall()
; конечным результатом является то же, но вместо этого вы упустили возможность транслировать результаты.