2010-03-24 37 views
36

¿Cómo puedo acceder al número de filas afectadas por:Python: Número de filas afectadas por cursor.execute ("SELECT ...)

cursor.execute("SELECT COUNT(*) from result where server_state='2' AND name LIKE '"+digest+"_"+charset+"_%'") 
+30

Esta pregunta no tiene sentido. Una instrucción select no afecta a ** ninguna ** filas. –

+4

Creo que la intención es obtener el número de filas devuelto por 'COUNT (*)' lo que significa que la pregunta real es "Cómo acceder al resultado de' cursor.execute'. – lmichelbacher

+4

También nunca, NUNCA use concatenaciones de cadenas de Python vea http : //initd.org/psycopg/docs/usage.html#the-problem-with-the-query-parameters, o estarás en el mundo del dolor! – Alex

Respuesta

49

Intente utilizar fetchone:

cursor.execute("SELECT COUNT(*) from result where server_state='2' AND name LIKE '"+digest+"_"+charset+"_%'") 
result=cursor.fetchone() 

result llevará a cabo una tupla con un elemento, el valor de COUNT(*). Así que para encontrar el número de filas:

number_of_rows=result[0] 

O, si prefiere hacerlo de una sola vez:

cursor.execute("SELECT COUNT(*) from result where server_state='2' AND name LIKE '"+digest+"_"+charset+"_%'") 
(number_of_rows,)=cursor.fetchone() 

PS. También es una buena práctica usar argumentos parametrizados siempre que sea posible, ya que puede citar automáticamente los argumentos cuando sea necesario y protegerlos contra la inyección de sql.

La sintaxis correcta para los argumentos parametrizados depende de su adaptador de python/base de datos (por ejemplo, mysqldb, psycopg2 o sqlite3). Se vería algo así como

cursor.execute("SELECT COUNT(*) from result where server_state= %s AND name LIKE %s",[2,digest+"_"+charset+"_%"]) 
(number_of_rows,)=cursor.fetchone() 
+0

el método anterior no es compatible con psycopg2 porque fetchone espera un parámetro (self), no two-fetchone, no espera una consulta como argumento. –

+0

¡Gracias por la corrección! – unutbu

+0

La sustitución de cadena de Python normal a instrucciones de compilación no es el enfoque preferido. O como dice la documentación oficial ["¡Nunca hagas esto, inseguro!"] (Https://docs.python.org/2/library/sqlite3.html). Use la sintaxis '?' En su lugar. – lmichelbacher

82

De PEP 249, que por lo general se implementa mediante las API de base de datos de Python:

objetos cursor debe responder a los siguientes métodos y atributos:

[...]

.rowcoun t
Este atributo de solo lectura especifica el número de filas que produjo el último .execute *() (para sentencias DQL como 'seleccionar') o afectadas (para sentencias DML como 'actualizar' o 'insertar').

Espero que sea eso lo que quiso decir.

+2

. La cuenta para Seleccionar parece ser siempre 1 –

+5

@ Tie-fighter: Se produjo una fila, que contiene el valor 'COUNT (*)'. Si consulta 'SELECT name FROM result WHERE server_state = '2'', por ejemplo, obtendrá cero, una o varias filas. – AndiDog

+10

SQLite * always * produce' cursor.rowcount == -1' para sentencias 'SELECT' como no sabe cuántas filas se devolverán hasta que haya devuelto todas las filas; son iteradores hasta abajo para SQLite. –

31

El número de filas efectuado se volvió de ejecutar:

rows_affected=cursor.execute("SELECT ... ") 

por supuesto, como AndiDog ya se ha mencionado, se puede obtener el número de filas mediante el acceso a la propiedad de recuento de filas de la cursor en cualquier momento para obtener el número de la última ejecutar:

cursor.execute("SELECT ... ") 
rows_affected=cursor.rowcount 

de la documentación en línea de MySQLdb pitón:

def execute(self, query, args=None): 

    """Execute a query. 

    query -- string, query to execute on server 
    args -- optional sequence or mapping, parameters to use with query. 

    Note: If args is a sequence, then %s must be used as the 
    parameter placeholder in the query. If a mapping is used, 
    %(key)s must be used as the placeholder. 

    Returns long integer rows affected, if any 

    """ 
+2

+1 Boaz, "rows_affected = cursor.rowcount" es absolutamente la mejor respuesta. No requiere una consulta adicional ya que el valor siempre está presente. rowcount es útil para determinar el número de registros insertados, actualizados, eliminados o recuperados a través de una consulta. –

+11

De acuerdo con lo ya mencionado [PEP 249] (http://www.python.org/dev/peps/pep-0249/), el valor devuelto por el método 'cursor.execute 'ya no está definido (en la versión anterior de la especificación se esperaba que funcionara como en el ejemplo de Boaz). La especificación sugiere explícitamente el uso de _el atributo .rowcount más flexible en su lugar_ ya que el valor devuelto por el método 'execute' depende de la implementación de la interfaz de la base de datos. –

+1

@Boaz - Encontré que este enfoque NO FUNCIONABA para MariaDB 10.4.17, Python 2.7.8 y Connector/Python 2.0.4. Lamentablemente, no pude encontrar CUALQUIER enfoque publicado que funcionó para esa combinación de herramientas. ¡Finalmente tuve que recorrer las filas y contarlas yo mismo! – SMGreenfield

17

En mi opinión, la forma más sencilla de obtener la cantidad de filas seleccionadas es la siguiente:

El objeto de cursor devuelve una lista con los resultados cuando se utilizan los comandos fetch (fetchall(), fetchone() , fetchmany()). Para obtener las filas seleccionadas, simplemente imprima la longitud de esta lista. Pero simplemente tiene sentido para fetchall().;-)

Ejemplo:

print len(cursor.fetchall) 
+0

esto es más directo y funcionó como un encanto. Gracias. – Anthony

+0

lo que funciona para mí es imprimir len (cursor.fetchall()) – alvaro562003

+0

¿Existe diferencia de rendimiento al usar len()? –

1

para MySQL forma más sencilla es esta

mycur.execute("SELECT COUNT(*) FROM osreport") 
print(mycur.fetchall()) 
0

// esto funciona para mí. U puede usar de esta manera

query = "select count(id) from test" 
cursor.execute(query) 
var = cursor.fetchone() 
print var[0] 
Cuestiones relacionadas