2012-10-30 14 views
9

Kann jemand die Zeilenanzahl von einem SQL-Alchemy-Abfrage-ResultProxy-Objekt erhalten, ohne die Ergebnismenge durchzulaufen? Das ResultProxy.rowcount-Attribut zeigt 0, ich würde erwarten, dass es einen Wert von 2 hat. Für Updates zeigt es die Anzahl der betroffenen Zeilen an, was ich erwarten würde.SQL-Alchemie ResultProxy.rowcount sollte nicht 0 sein

from sqlalchemy import create_engine 
from sqlalchemy.orm import sessionmaker 

engine = create_engine(
    'oracle+cx_oracle://user:[email protected]:port/database' 
    ) 

session = sessionmaker(
    bind = engine 
    , autocommit = False 
    , autoflush = False 
    )() 

sql_text = u""" 
    SELECT 1 AS Val FROM dual UNION ALL 
    SELECT 2 AS Val FROM dual 
    """ 

results = session.execute(sql_text) 

print '%s rows returned by query...\n' % results.rowcount 
print results.keys() 

for i in results: 
    print repr(i) 

Ausgang:

0 rows returned by query... 

[u'val'] 
(1,) 
(2,) 

Antwort

14

resultproxy.rowcount ist letztlich ein Proxy für das DBAPI Attribut cursor.rowcount. Die meisten DBAPIs bieten die "Anzahl der Zeilen" für eine SELECT-Abfrage nicht über dieses Attribut; Der Hauptzweck besteht darin, die Anzahl der Zeilen anzugeben, die von einer UPDATE- oder DELETE-Anweisung abgeglichen werden. Eine relationale Datenbank weiß tatsächlich nicht, wie viele Zeilen von einer bestimmten Anweisung zurückgegeben werden, bis sie alle diese Zeilen gefunden hat. Viele DBAPI-Implementierungen beginnen mit der Rückgabe von Zeilen, wenn die Datenbank sie ohne Pufferung findet, sodass in diesen Fällen keine solche Anzahl verfügbar ist.

Um die Anzahl der Zeilen zu erhalten, die eine SELECT-Abfrage zurückgeben würde, müssen Sie entweder einen SELECT COUNT (*) ausführen, oder Sie müssen alle Zeilen in ein Array holen und len() für das Array ausführen.

Die Noten bei ResultProxy.rowcount diskutieren diese weiter (http://docs.sqlalchemy.org/en/latest/core/connections.html?highlight=rowcount#sqlalchemy.engine.ResultProxy.rowcount):

Hinweise zu ResultProxy.rowcount:

  • Dieses Attribut gibt die Anzahl der Zeilen zurückgibt abgestimmt, die nicht unbedingt die gleiche wie die Anzahl der Zeilen, die tatsächlich geändert wurden - eine Anweisung UPDATE zum Beispiel haben keine Nettoänderung für eine gegebene Zeile, wenn die angegebenen SET-Werte mit denen in der Zeile übereinstimmen bereits. Solch eine Zeile würde übereinstimmen, aber nicht geändert werden. Bei Backends , die beide Stile enthalten, z. B. MySQL, wird rowcount standardmäßig von konfiguriert, um die Übereinstimmungsanzahl in allen Fällen zurückzugeben.

  • ErgebnisProxy.rowcount ist nur nützlich in Verbindung mit einer UPDATE oder DELETE-Anweisung. Im Gegensatz zu dem, was die Python-DBAPI sagt, gibt es nicht die Anzahl der verfügbaren Zeilen aus den Ergebnissen einer SELECT -Anweisung als DBAPIs kann diese Funktionalität nicht unterstützen, wenn Zeilen ungepuffert sind.

  • ResultProxy.rowcount ist möglicherweise nicht vollständig von allen Dialekten implementiert. Insbesondere unterstützen die meisten DBAPIs kein gesamtes Zeilenzählerergebnis von einem ausführenden Aufruf. Die Methoden ResultProxy.supports_sane_rowcount() und ResultProxy.supports_sane_multi_rowcount() melden den Dialekt von , wenn bekannt ist, dass jede Verwendung unterstützt wird.

  • Anweisungen, die RETURNING verwenden, geben möglicherweise keine korrekte Zeilenanzahl zurück.
1

könnten Sie verwenden:

rowcount = len(results._saved_cursor._result.rows) 

Dann wird Ihr Code

sein
print '%s rows returned by query...\n' % rowcount 
print results.keys() 

Nur getestet 'finden' frägt

Es funktioniert für mich.