2009-05-08 12 views
18

Sto cercando di ottenere il rowcount di un sqlite3cursor nel mio programma Python3k, ma io sono perplesso, come il rowcount è sempre -1, nonostante quello che dicono docs python3 (in realtà è contraddittorio, dovrebbe essere None). Anche dopo aver recuperato tutte le righe, rowcount resta -1. È un bug sqlite3? Ho già controllato se ci sono righe nella tabella.cursor.rowcount sempre -1 in sqlite3 in python3k

Posso aggirare questo controllo se un fetchone() restituisce qualcosa di diverso da None, ma ho pensato che questo problema sarebbe stato carino da discutere.

Grazie.

+0

"in realtà è contraddittoria ..." Si prega di fornire un riferimento o un link per questo. –

+0

http://docs.python.org/3.0/library/sqlite3.html?highlight=sqlite#sqlite3.Cursor Forse ho sbagliato, ma l'ultimo paragrafo di Cursor.rowcount dice "Questo include le istruzioni SELECT perché non possiamo determinare il numero di righe di una query prodotta fino a quando tutte le righe sono state recuperate. " Quindi ho indovinato che dopo aver recuperato witch fetchone() o fetchall() avrei ottenuto un conteggio aggiornato. grazie – Hiperi0n

+0

Quando si utilizza il pacchetto 'mysql.connector' l'attributo rowcount è -1 dopo una chiamata .execute di un'istruzione SELECT, ma dopo la chiamata a fetchall() il numero effettivo di righe nei dati' fetch'ed è restituito. Solo un'osservazione ... – Duffau

risposta

16

Dal documentation:

quanto richiesto dalla Python DB API Spec, l'attributo rowcount “è -1 in caso senza executeXX() è stata eseguita sulla cursore o il conteggio delle righe della l'ultima operazione non è determinabile dall'interfaccia ".

Questo include SELECT dichiarazioni perché non si può determinare il numero di righe una query produce fino a quando tutte le righe sono state recuperate .

Ciò significa tuttiSELECT dichiarazioni non avrà un rowcount. Il comportamento che stai osservando è documentato.

EDIT: documentazione non dice da nessuna parte che rowcountsarà essere aggiornati dopo si fa un fetchall() quindi è solo sbagliato pensare che.

8

Invece di "controllare se un fetchOne() restituisce qualcosa di diverso da Nessuno", suggerisco:

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

questo è sqlite -solo (non supportato in altre implementazioni API DB), ma molto utile per sqlite - codice Python specifico (e completamente documentato, vedere http://docs.python.org/library/sqlite3.html).

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

Il fetchall() restituirà un elenco delle righe restituite dalla selezione. Len di quella lista ti darà il conteggio delle righe.

+1

L'avvertimento principale di questo è - se c'è un cambiamento che questa chiamata restituirebbe una quantità eccessiva di righe - potresti finire con problemi di memoria. (Questo è il motivo per cui execute restituisce un cursore [Python iterator] piuttosto che restituire un elenco o un array esplicito). (Anche se nel mio caso particolare, questo non era un problema.) – Brad

7

possa meglio contare le righe in questo modo:

print cur.execute("SELECT COUNT(*) FROM table_name").fetchone()[0] 
-2

Utilizzando PyCharm, in modalità di debug, se si mette il cursore sul variabile di cursore, apparirà una piccola +, quando si fa clic su di esso, si vede diverse proprietà del tuo oggetto.

Nel mio cursore di 1 elemento, vedo:

rowcount={int} 
arraysize={int}1 

Così, nel codice, basta usare:

print(cursor.arraysize) 
1 
+0

L'array di cursori controlla quante righe vengono restituite da 'fetchmany()', ed è 1 di default. Non ha nulla a che fare con il conteggio delle righe –