SQLalchemy rowcount immer -1 für Anweisungen

Nov 16 2020

Ich habe mit SQLalchemy und Microsoft SQL Server herumgespielt, um einen Überblick über die Funktionen zu bekommen, als ich auf ein seltsames Verhalten stieß. Mir wurde beigebracht, dass das Attribut rowcount für das Ergebnis-Proxy-Objekt angibt, wie viele Zeilen durch Ausführen einer Anweisung betroffen waren. Wenn ich jedoch einzelne oder mehrere Zeilen in meine Testdatenbank auswähle oder einfüge, erhalte ich immer -1. Wie könnte das sein und wie kann ich das beheben, um die Realität widerzuspiegeln?

connection = engine.connect()
metadata = MetaData()

# Ex1: select statement for all values
student = Table('student', metadata, autoload=True, autoload_with=engine)
stmt = select([student])
result_proxy = connection.execute(stmt)
results = result_proxy.fetchall()
print(result_proxy.rowcount)

# Ex2: inserting single values
stmt = insert(student).values(firstname='Severus', lastname='Snape')
result_proxy = connection.execute(stmt)
print(result_proxy.rowcout)
 
# Ex3: inserting multiple values 
stmt = insert(student)
values_list = [{'firstname': 'Rubius', 'lastname': 'Hagrid'},
               {'firstname': 'Minerva', 'lastname': 'McGonogall'}]
result_proxy = connection.execute(stmt, values_list)
print(result_proxy.rowcount)

Die Druckfunktion für jeden Block führt separat Beispielcode-Drucke -1 aus. Der Ex1 ruft erfolgreich alle Zeilen ab und beide Einfügeanweisungen schreiben die Daten erfolgreich in die Datenbank.

Gemäß dem folgenden Problem ist das Attribut rowcount nicht immer vertrauenswürdig. Gilt das auch hier? Und wann, wie kann ich mit einer Count-Anweisung in einer SQLalcehmy-Transaktion kompensieren? PDO :: rowCount () gibt -1 zurück

Antworten

1 GordThompson Nov 19 2020 at 02:46

Die einzelne Zeile INSERT … VALUES ( … )ist trivial: Wenn die Anweisung erfolgreich ist, war eine Zeile betroffen, und wenn sie fehlschlägt (einen Fehler auslöst), waren null Zeilen betroffen.

Führen Sie eine mehrzeilige Datei INSERTeinfach innerhalb einer Transaktion aus und führen Sie einen Rollback durch, wenn ein Fehler auftritt. Dann ist die Anzahl der betroffenen Zeilen entweder Null oder len(values_list).

Um die Anzahl der Zeilen zu erhalten , dass eine SELECT wird zurückkehren, wickeln Sie die Auswahlabfrage in einer SELECT count(*)Abfrage und führen Sie das erste, zum Beispiel:

select_stmt = sa.select([Parent])
count_stmt = sa.select([sa.func.count(sa.text("*"))]).select_from(
    select_stmt.alias("s")
)
with engine.connect() as conn:
    conn.execution_options(isolation_level="SERIALIZABLE")
    rows_found = conn.execute(count_stmt).scalar()
    print(f"{rows_found} row(s) found")
    results = conn.execute(select_stmt).fetchall()
for item in results:
    print(item.id)