Python: Number of rows affected by cursor.execute("SELECT ...)


Question

How can I access the number of rows affected by:

cursor.execute("SELECT COUNT(*) from result where server_state='2' AND name LIKE '"+digest+"_"+charset+"_%'")
1
47
3/24/2010 9:52:54 PM

Accepted Answer

Try using fetchone:

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

result will hold a tuple with one element, the value of COUNT(*). So to find the number of rows:

number_of_rows=result[0]

Or, if you'd rather do it in one fell swoop:

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

PS. It's also good practice to use parametrized arguments whenever possible, because it can automatically quote arguments for you when needed, and protect against sql injection.

The correct syntax for parametrized arguments depends on your python/database adapter (e.g. mysqldb, psycopg2 or sqlite3). It would look something like

cursor.execute("SELECT COUNT(*) from result where server_state= %s AND name LIKE %s",[2,digest+"_"+charset+"_%"])
(number_of_rows,)=cursor.fetchone()
66
12/5/2011 12:21:44 PM

From PEP 249, which is usually implemented by Python database APIs:

Cursor Objects should respond to the following methods and attributes:

[…]

.rowcount
This read-only attribute specifies the number of rows that the last .execute*() produced (for DQL statements like 'select') or affected (for DML statements like 'update' or 'insert').

But be careful—it goes on to say:

The attribute is -1 in case no .execute*() has been performed on the cursor or the rowcount of the last operation is cannot be determined by the interface. [7]

Note:
Future versions of the DB API specification could redefine the latter case to have the object return None instead of -1.

So if you've executed your statement, and it works, and you're certain your code will always be run against the same version of the same DBMS, this is a reasonable solution.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon