I'm looking for a way to programatically determine the difference between cur.rowcount
describing the number of rows available to fetch versus the number of rows affected.
For example:
>>> cur.execute('CREATE TABLE test (gid serial, val numeric);')
>>> cur.execute('INSERT INTO test (val) values (1), (2), (3);')
>>> cur.execute('SELECT * FROM test;'); cur.rowcount
3
>>> cur.execute('UPDATE test SET val = 1;'); cur.rowcount
3
>>> cur.fetchall()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
psycopg2.ProgrammingError: no results to fetch
>>> cur.execute('DELETE FROM test;'); cur.rowcount
3
>>> cur.execute('DROP TABLE test;')
>>> cur.rowcount
-1
Using Python 2.7 and psycopg2 2.6.2.
There is the psycopg2.errors module you should make use of. There is a complete list in the docs commit () can't be used to get the row count, but you can use the cursor to get that information after each execute call. You can use its rowcount attribute to get the number of rows affected for SELECT, INSERT, UPDATE and DELETE.
@@ROWCOUNT returns the affected rows from any statement, even if it’s not DML or a SELECT query. To avoid this kind of scenario, you can store the row count in a local variable. The script would then look like this: DECLARE @rowcount INT; BEGIN TRY SELECT TOP 100 * FROM [AdventureWorks2017]. [Person].
SET NOCOUNT ON also doesn’t affect @@ROWCOUNT. SET NOCOUNT tells SQL Server to stop displaying the message with the number of rows affected by a query. However, @@ROWCOUNT is still updated. Let’s illustrate with an example.
Typically, @@ROWCOUNT is used for error handling or for checking a business rule. You can access @@ROWCOUNT like any other variable in an IF statement. For example: In this script, we perform an UPDATE statement. After the statement is done, we check if any rows were updated at all.
The distinction is simple at least in theory rowcount
would be returned for all the DQL (Data Query Language) and DML (Data Manipulation Language) queries (your SELECT
, UPDATE
, DELETE
etc). You'll have -1
for DDL (Data Definition Language) queries - the (CREATE
, DROP
, ALTER
etc).
In other words, you can expect rowcount
to be defined (meaning >=0) if you actually manipulate data; if you work with the database/table schema - you'll have rowcount = -1
.
As far as determining when the fetchall()
would work or not, you can always go with the EAFP approach - try executing fetchall()
and handle the ProgrammingError
.
Also see:
According to the docs, cur.description
will be None
for operations without a result set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With