2009-05-08 4 views
18

Ich versuche, die rowcount ein sqlite3cursor in meinem Python3k Programm zu erhalten, aber ich bin verwirrt, wie die rowcount immer -1 ist, trotz allem, was Python3 docs sagen (eigentlich ist es widersprüchlich, sollte es None sein). Auch nach dem Abrufen aller Zeilen bleibt rowcount bei -1. Ist es ein sqlite3 Bug? Ich habe bereits überprüft, ob Zeilen in der Tabelle sind.cursor.rowcount immer -1 in sqlite3 in python3k

Ich kann diese Überprüfung umgehen, wenn ein etwas anderes als None zurückgibt, aber ich dachte, dieses Thema wäre schön zu diskutieren.

Danke.

+0

"eigentlich ist es widersprüchlich ist ..." Bitte geben Sie einen Verweis oder ein Link dafür. –

+0

http://docs.python.org/3.0/library/sqlite3.html?highlight=sqlite#sqlite3.Cursor Vielleicht habe ich es falsch gemacht, aber der letzte Absatz von Cursor.rowcount sagt "Dies beinhaltet SELECT-Anweisungen, weil wir nicht können Ermitteln Sie die Anzahl der Zeilen, die eine Abfrage erzeugt hat, bis alle Zeilen abgerufen wurden. " Ich vermutete, dass ich nach dem Abholen von fetchone() oder fetchall() einen aktualisierten Zeilenzähler erhalten würde. danke – Hiperi0n

+0

Wenn Sie das Paket mysql.connector verwenden, ist das rowcount Attribut -1 nach einem .execute Aufruf einer SELECT-Anweisung, aber nach dem fetchall() Aufruf ist die tatsächliche Anzahl der Zeilen in den 'fetch'ed Daten ist zurückgekommen. Nur eine Beobachtung ... – Duffau

Antwort

16

Vom documentation:

Wie von der Python DB API Spec, das rowcount Attribut „-1 ist, falls kein executeXX() auf der Cursor oder die rowcount der durchgeführt wurde letzte Operation ist nicht durch die Schnittstelle bestimmbar ".

Dazu gehören SELECT Aussagen , weil wir nicht die Anzahl der Zeilen eine Abfrage erzeugt bestimmen kann, bis alle Zeilen abgerufen wurden.

Das heißt alleSELECT Aussagen keinen rowcount haben. Das Verhalten, das Sie beobachten, ist dokumentiert.

EDIT: Dokumentation nicht sagen, überall, dass rowcountwird aktualisiert werden, nachdem Sie ein fetchall() tun, so dass es einfach falsch ist, dass zu übernehmen.

8

Statt "überprüft, ob ein fetchone() etwas anderes als None zurückgibt", schlage ich vor:

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

diese sqlite -nur ist (nicht in anderen DB-API-Implementierungen unterstützt), aber sehr praktisch für sqlite - spezifischer Python-Code (und vollständig dokumentiert, siehe http://docs.python.org/library/sqlite3.html).

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

Die Funktion fetchall() gibt eine Liste der Zeilen zurück, die von der Auswahl zurückgegeben wurden. Len dieser Liste gibt Ihnen die Anzahl der Zeilen.

+1

Der Hauptvorbehalt davon ist - wenn es eine Änderung gibt, dass dieser Aufruf eine übermäßige Menge von Zeilen zurückgeben würde - könnten Sie mit Speicherproblemen enden. (Aus diesem Grund gibt execute einen Cursor [Python-Iterator] zurück, anstatt eine explizite Liste oder ein Array zurückzugeben). (In meinem speziellen Fall war dies jedoch kein Problem.) – Brad

7

besser Mai die Zeilen auf diese Weise zählen:

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

Mit PyCharm, im Debug-Modus, wenn Sie mit dem Cursor auf dem Cursor-Variable setzen, wird ein kleiner + erscheinen, wenn Sie darauf klicken, sehen Sie verschiedene Eigenschaften Ihres Objekts.

In meinem Cursor von 1 Element, ich sehe:

rowcount={int} 
arraysize={int}1 

in Ihrem Code So, benutzen Sie einfach:

print(cursor.arraysize) 
1 
+0

Die Array-Größe des Cursors steuert, wie viele Zeilen von 'fetchmany()' zurückgegeben werden, und ist standardmäßig 1. Es hat nichts mit der Zeilenanzahl zu tun –