New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mariadbconnector: Exception "cursor is closed" raised, when checking cursor.rowcount #10396
Comments
|
well they are calling result.rowcount on an insert statement. Most DBAPIs don't produce any meaningful number for rowcount with INSERT, which implies we could hardcode this case to return -1, but then, some DBAPIs do produce a meaningful number, such as the sqlite driver, and we would assume mariadb-connector here as well. the problem with rowcount is that it often produces an extra database query. So a naive fix here, "pre-load rowcount for all INSERT statements", adds this extra database query penalty to millions of SQLAlchemy installations in all cases, to suit what is IMO nearly a non-usecase. Alternatively, we could express that "rowcount is only for UPDATE /DELETE, you will get -1 for other operations", however that's the quagmire here, some drivers do return a meaningful number for INSERT statements so we can't just switch that.
is calling a data accessor a "read only operation" ? Many DBAPIs have this value passively present at cursor.rowcount after a DML operation, hence no issue with exceptions. I certainly hope that mariadb-connector is not enforcing a needless exception raise here if it does not actually need to run a new query to get the rowcount. otherwise if the driver does need to run a new query, then this limitation is typical, though the majority of drivers don't have this limitation (otherwise this issue would be occurring for many drivers). Since most drivers dont have this limitation, we can't really be sure how many users are calling .rowcount after non UPDATE/DELETE operations, though the fact that pandas seems to hardcode it for all SQL operations suggests it's very widespread, and then the number (which is for many drivers simply -1) is thrown away. I think in this case what we should do is modify the mariadb-connector driver itself to tl;dr we've never supported .rowcount for an INSERT statement so behavior is defined as pass-through to raw cursor for now. |
|
additionally as you may or may not be aware we had to remove mariadb-connector from our CI in December of 2022 as it was producing releases on pypi that relied upon bleeding edge client libraries that were not yet available in Fedora (366a5e3) . I can attempt to re-add mariadb-connector to CI now assuming things have calmed down but I continue to not have a solution to this problem if mariadb-connector puts out releases using bleeding-edge client libraries. |
|
the change I'm adding will add the
|
|
Mike Bayer has proposed a fix for this issue in the main branch: invoke mariadb-connector .rowcount after all statements https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4891 |
|
Hello Mike, thank you for your comments - I think the simplest solution would be if I just remove the check for closed cursor in cursor properties (e.g. rowcount), as long the properties aren't directly mapped to some underlying data (like result sets or prepared statements) which were freed in close() method. |
|
OK that's fine, my patch here at least adds test support for this case so has to go in to that extent anyway, does cursor.rowcount in mariadb-connector invoke a new query and/or does it have significant round-trip overhead? |
|
No, it's stored internally and works for upsert and select statements. I think your idea, to return -1 is even better than returning any value. |
|
OK. if there's no overhead I can keep my fix in place in any case |
we can probably leave a comment on the fix mentioning that it's no longer needed on x.y.z version of the connector (since from Georg comment it seems the idea is to remove the expection in this case) |
|
@zzzeek where did this land? I read through all the comments here ( I was the one that originally raised the issue via MariaDB ), but I'm not clear on whether this has been released yet? |
|
It was meeged in the main branch 2 weeks ago. Since the last release was 3 weeks ago it's not yet released. It should be released this week or the next |
Describe the bug
The problem was initially reported on stackoverflow, similiar issue was filed as MariaDB Connector/Python bug. I'm not sure if this problem is caused by Pandas or SQLAlchemy.
MariaDB Connector/Python raises an exception "Cursor is closed" in cursor->rowcount, since the cursor was closed before.
PyMySQL for example doesn't raise an exception, which is in contradiction to PEP-249: ".close(): ... The cursor will be unusable from this point forward; an Error (or subclass) exception will be raised if any operation is attempted with the cursor".
Optional link from https://docs.sqlalchemy.org which documents the behavior that is expected
No response
SQLAlchemy Version in Use
2.0.21
DBAPI (i.e. the database driver)
mariadbconnector
Database Vendor and Major Version
MariaDB 11.0
Python Version
3.10
Operating system
Linux, Windows
To Reproduce
Error
Stacktrace (when closing the cursor):
Stacktrace (cursor->rowcount):
Additional context
No response
The text was updated successfully, but these errors were encountered: