length fetchone python cursor mysql-python

fetchone - python mysql cursor length



cursor.fetchall() vs list(cursor) en Python (4)

Ambos métodos devuelven una lista de los elementos devueltos de la consulta, ¿perdí algo aquí?
¿O tienen usos idénticos en verdad?
¿Alguna diferencia en cuanto al rendimiento?


Una diferencia (específica de MySQLdb / PyMySQL) que vale la pena notar cuando se usa un DictCursor es que la list(cursor) siempre le dará una lista, mientras que cursor.fetchall() le da una lista a menos que el conjunto de resultados esté vacío, en cuyo caso le da Eres una tupla vacía. Este fue el caso en MySQLdb y sigue siendo el caso en el nuevo PyMySQL , donde no se solucionará por razones de compatibilidad con versiones anteriores. Si bien esto no es una violación de la especificación de la API de la base de datos de Python , aún es sorprendente y puede conducir fácilmente a un error de tipo causado por asumir erróneamente que el resultado es una lista , en lugar de solo una secuencia .

Dado lo anterior, sugiero siempre favorecer la list(cursor) sobre cursor.fetchall() , para evitar que un error de tipo misterioso lo cursor.fetchall() en el caso de borde donde el conjunto de resultados está vacío.


cursor.fetchall() y list(cursor) son esencialmente los mismos. La opción diferente es no recuperar una lista y, en su lugar, simplemente recorrer el objeto del cursor:

for result in cursor:

Esto puede ser más eficiente si el conjunto de resultados es grande, ya que no tiene que obtener todo el conjunto de resultados y mantenerlo en la memoria; puede obtener cada artículo de forma incremental (o agruparlos en lotes más pequeños).


list(cursor) funciona porque un cursor es un iterable; También puedes usar el cursor en un bucle:

for row in cursor: # ...

Una buena implementación del adaptador de base de datos recuperará filas en lotes desde el servidor, guardando en la huella de memoria requerida, ya que no tendrá que mantener todo el conjunto de resultados en la memoria. cursor.fetchall() tiene que devolver la lista completa.

No tiene mucho sentido usar list(cursor) sobre cursor.fetchall() ; el efecto final es entonces el mismo, pero en lugar de eso, perdiste la oportunidad de transmitir resultados.


Si está utilizando el cursor predeterminado, un MySQLdb.cursors.Cursor , todo el conjunto de resultados se almacenará en el lado del cliente (es decir, en una lista de Python) en el momento en que se completa el cursor.execute() .

Por lo tanto, incluso si usas

for row in cursor:

No obtendrá ninguna reducción en la huella de memoria. El conjunto de resultados completo ya se ha almacenado en una lista (vea self._rows en MySQLdb / cursors.py).

Sin embargo, si utiliza un SSCursor o SSDictCursor:

import MySQLdb import MySQLdb.cursors as cursors conn = MySQLdb.connect(..., cursorclass=cursors.SSCursor)

entonces el conjunto de resultados se almacena en el servidor , mysqld. Ahora puedes escribir

cursor = conn.cursor() cursor.execute(''SELECT * FROM HUGETABLE'') for row in cursor: print(row)

y las filas se buscarán una por una desde el servidor, por lo que no se requiere que Python cree primero una gran lista de tuplas, y así se guarda en la memoria.

De lo contrario, como ya han dicho otros, cursor.fetchall() y list(cursor) son esencialmente lo mismo.