2012-10-12 220 views
19

Me gustaría obtener el resultado de la operación fetchall en una lista en lugar de la tupla de tupla o tupla de diccionarios. Por ejemplo,Python MySQLDB: Obtenga el resultado de fetchall en una lista

cursor = connection.cursor() #Cursor could be a normal cursor or dict cursor 
query = "Select id from bs" 
cursor.execute(query) 
row = cursor.fetchall() 

Ahora, el problema es la fila resultante es o bien ((123,), (234,)) o ({ 'id': 123}, { 'id': 234}) Lo que estoy buscando es (123,234) o [123,234]. Sé mejor si puedo ahorrar en el análisis del resultado. Gracias de antemano

+0

Probablemente tiene que proporcionar una clase personalizada Cursor para hacer esto. Los backends django db hacen esto, así que puedes buscar inspiración allí. Por ejemplo, 'django.db.backends.mysql.base.CursorWrapper' se usa sobre el Cursor MySQL, pero no estoy seguro de dónde está registrado. Puede significar proporcionar un back-end db personalizado que devuelva tu Cursor personalizado. Es probable que sea más fácil analizar los datos que necesita al acceder a él. – dokkaebi

Respuesta

38

¿Y qué hay de la lista de comprensiones? Si el resultado es ((123,), (234,), (345,)):

>>> row = [item[0] for item in cursor.fetchall()] 
>>> row 
[123, 234, 345] 

si el resultado se ({'id': 123}, {'id': 234}, {'id': 345}):

>>> row = [item['id'] for item in cursor.fetchall()] 
>>> row 
[123, 234, 345] 
+4

Amigo Lo mencioné, estoy tratando de evitar esto. Esperaba que el cursor se pudiera programar de forma que el resultado se pudiera obtener directamente en la lista. –

+1

Entonces, si este escenario es solo un ejemplo, ¿cómo piensa hacerlo con consultas que tienen más de un campo? Es por eso que obtienes una tupla de tuplas en primer lugar –

+0

¿Quién dijo que es un ejemplo? Solo quiero buscar una sola columna de identificadores y el recuento de filas está en millones. Quiero hacer un procesamiento posterior de los datos y es por eso que estoy tratando de encontrar una manera de evitar esta costosa operación. –

1

Si sólo hay un campo, puedo usar esto para hacer una lista de la base de datos:

def getFieldAsList(): 
    kursor.execute("Select id from bs") 
    id_data = kursor.fetchall() 
    id_list = [] 
    for index in range(len(id_data)): 
     id_list.append(id_data[index][0]) 
    return id_list 
-4
cursor.execute("""Select * From bs WHERE (id = %s)""",(id)) 

cursor.fetchall() 
13

Estoy seguro de que después de todo este tiempo, ha resuelto este problema, sin embargo, para algunas personas que no pueden saber cómo obtener los valores de un cursor como un diccionario utilizando MySQLdb, puede utilizar este método encontró here:

import MySQLdb as mdb 

con = mdb.connect('localhost', 'testuser', 'test623', 'testdb') 

with con: 

    cur = con.cursor(mdb.cursors.DictCursor) 
    cur.execute("SELECT * FROM Writers LIMIT 4") 

    rows = cur.fetchall() 

    for row in rows: 
     print row["Id"], row["Name"] 
7

Este viejo Q aparece en Google durante la búsqueda de aplanamiento consultas db, así que aquí están más sugerencias. ..

Considere un rápido list-flattening iterator.

Otras respuestas usan fetchall() que primero carga todas las filas en la memoria, luego itera sobre eso para hacer una nueva lista. Podría ser ineficiente Podría combinar con MySQL llamada server side cursor:

# assume mysql on localhost with db test and table bs 
import itertools 
import MySQLdb 
import MySQLdb.cursors 

conn = MySQLdb.connect(host='localhost',db='test', 
      cursorclass=MySQLdb.cursors.SSCursor) 
cursor = conn.cursor() 
# insert a bunch of rows 
cursor.executemany('INSERT INTO bs (id) VALUES (%s)',zip(range(1,10000))) 
conn.commit() 
# retrieve and listify 
cursor.execute("select id from bs") 
list_of_ids = list(itertools.chain.from_iterable(cursor)) 
len(list_of_ids) 
#9999 
conn.close() 

Pero la cuestión también está etiquetada Django, que tiene una bonita single field query flattener

class Bs(models.Model): 
    id_field = models.IntegerField() 

list_of_ids = Bs.objects.values_list('id_field', flat=True) 
+0

Un par de años tarde, pero esto es lo que OP estaba preguntando: cree una lista sin usar fetch all() debido al número de sus puntos de datos. –

Cuestiones relacionadas