Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cursor.rowcount always -1 in sqlite3 in python3k

I am trying to get the rowcount of a sqlite3 cursor in my Python3k program, but I am puzzled, as the rowcount is always -1, despite what Python3 docs say (actually it is contradictory, it should be None). Even after fetching all the rows, rowcount stays at -1. Is it a sqlite3 bug? I have already checked if there are rows in the table.

I can get around this checking if a fetchone() returns something different than None, but I thought this issue would be nice to discuss.

Thanks.

like image 374
Hiperi0n Avatar asked May 08 '09 09:05

Hiperi0n


5 Answers

From the documentation:

As required by the Python DB API Spec, the rowcount attribute “is -1 in case no executeXX() has been performed on the cursor or the rowcount of the last operation is not determinable by the interface”.

This includes SELECT statements because we cannot determine the number of rows a query produced until all rows were fetched.

That means all SELECT statements won't have a rowcount. The behaviour you're observing is documented.

EDIT: Documentation doesn't say anywhere that rowcount will be updated after you do a fetchall() so it is just wrong to assume that.

like image 148
nosklo Avatar answered Oct 18 '22 09:10

nosklo


cursor = newdb.execute('select * from mydb;')
print len(cursor.fetchall())

The fetchall() will return a list of the rows returned from the select. Len of that list will give you the rowcount.

like image 41
user3320621 Avatar answered Oct 18 '22 09:10

user3320621


Instead of "checking if a fetchone() returns something different than None", I suggest:

cursor.execute('SELECT * FROM foobar')
for row in cursor:
   ...

this is sqlite-only (not supported in other DB API implementations) but very handy for sqlite-specific Python code (and fully documented, see http://docs.python.org/library/sqlite3.html).

like image 24
Alex Martelli Avatar answered Oct 18 '22 09:10

Alex Martelli


May better count the rows this way:

 print cur.execute("SELECT COUNT(*) FROM table_name").fetchone()[0]
like image 43
oxidworks Avatar answered Oct 18 '22 08:10

oxidworks


I've spent too long trying to find this, if you use this line you would want to use the .rowcount it should work for you. I'm using it to check if my statement will return any data.

    if (len(cursor.execute(sql).fetchall())) < 1: # checks there will be data by seeing if the length of the list make when getting the data is at least 1
        print("No data gathered from statement") #
    else:
       #RUN CODE HERE
like image 40
Rhys Broughton Avatar answered Oct 18 '22 09:10

Rhys Broughton