databases: Support returning the rowcount for a given query?
Hey! Thanks for this awesome library.
I’m replacing direct aiopg usage with it, but I ran into one issue that I can’t seem to solve. When executing a query aiopg returns an object with a .rowcount attribute. This is quite handy when using an INSERT ... ON CONFLICT query to know how many rows have been inserted.
I cannot seem to find out to how expose this information with this library. I’m guessing it might be more of an issue with asyncpg, but I was wondering if this is possible and if could be documented somewhere?
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 1
- Comments: 15 (10 by maintainers)
Currently we’re underspecifying the return type from
execute, and returning thelastrowidvalue.It looks like we probably ought to be returning a richer interface from that, with at least
.lastrowid, and.rowcountattributes being supported. Does that sound like the right interface to you folks?@tomchristie
executedoes not return feedback when deleting rows. Returning rows affected would be the standard MySQL way.https://github.com/encode/databases/blob/88b381ae33bcb417b76b8df9149742cbbcc253b5/databases/backends/mysql.py#L134
Always returns 0 because the row no longer exists.
Is there any way to get feedback from a delete?
Is there a separate issue tracking getting the count of affected rows from statements like
DELETE FROMandUPDATEor is this the one?Sorry, I wrote that in a bit of a rush. I meant we do not directly call asyncpg.execute() anywhere useful, and only use asyncpg wrappers around it like
fetch(). This means we don’t really expose a way to get the SQL status code.I think we should not go down this path. I asked in the #sqlalchemy IRC channel and they said that it’s mostly delegated to the underlying database driver.
Plus the
rowcountis available on classic DBAPI cursors that also return data, and it seems that usingreturningwould exclude any results from being fetched.All in all, having access to the
rowcountof the underling cursor would be really great, but it requires each of our backends to support it. Fixing it here seems to be the wrong layer.Edit: In that regard it seems
asyncpgis the only backend driver we support that doesn’t expose a rowcount attribute.I did a bit of digging. This issue is quite enlightening: https://github.com/MagicStack/asyncpg/issues/359
The tl;dr is that
execute()inasyncpgreturns the ‘status’ of the last command executed. This includes the rowcount: https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.connection.Connection.executeI’m not sure the best place to fix this. aiopg doesn’t seem to handle it itself. We could parse the status of the last SQL command that’s executed, but to complicate things we don’t really expose a way to call
.execute()without a raw connection (we only call wrappers like fetch).Urgh.