SQLalchemy rowcount siempre -1 para declaraciones
Estaba jugando con SQLalchemy y Microsoft SQL Server para familiarizarme con las funciones cuando me encontré con un comportamiento extraño. Me enseñaron que el atributo recuento de filas en el objeto de proxy de resultado dirá cuántas filas se realizaron al ejecutar una declaración. Sin embargo, cuando selecciono o inserto una o varias filas en mi base de datos de prueba, siempre obtengo -1. ¿Cómo podría ser esto y cómo puedo solucionarlo para reflejar la realidad?
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)
La función de impresión para cada bloque de código de ejemplo ejecutado por separado imprime -1. El Ex1 recupera con éxito todas las filas y ambas declaraciones de inserción escriben correctamente los datos en la base de datos.
Según el siguiente problema, no siempre se puede confiar en el atributo rowcount. ¿Es eso cierto aquí también? ¿Y cuándo, cómo puedo compensar con una declaración Count en una transacción SQLalcehmy? PDO :: rowCount () devolviendo -1
Respuestas
La fila única INSERT … VALUES ( … )es trivial: si la declaración tiene éxito, entonces una fila se vio afectada, y si falla (arroja un error), entonces cero filas se vieron afectadas.
Para una fila múltiple, INSERTsimplemente hágalo dentro de una transacción y retroceda si ocurre un error. Entonces el número de filas afectadas será cero o len(values_list).
Para obtener el número de filas que un SELECT será devolver, envolver la consulta de selección en una SELECT count(*)consulta y ejecutar la primera, por ejemplo:
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)