Skip to content
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

Closing a connection tries to close already closed cursors #497

Closed
betodealmeida opened this issue Jan 28, 2021 · 1 comment · Fixed by #498
Closed

Closing a connection tries to close already closed cursors #497

betodealmeida opened this issue Jan 28, 2021 · 1 comment · Fixed by #498
Assignees
Labels
api: bigquery Issues related to the googleapis/python-bigquery API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@betodealmeida
Copy link
Contributor

betodealmeida commented Jan 28, 2021

When closing a connection the library will call .close() on every cursor created for that connection, including closed ones. While the code works, it produces a lot of logs of error level, polluting the logs.

Environment details

  • OS type and version: Mac OS 10.15.7
  • Python version: Python 3.8.2
  • pip version: pip 20.3.3
  • google-cloud-bigquery version: 2.7.0

Steps to reproduce

  1. Close a cursor
  2. Close the connection
  3. Error log shows Exception closing connection <google.cloud.bigquery.dbapi.connection.Connection object at 0x...>

Code example

from contextlib import closing

# using pybigquery
with closing(engine.raw_connection()) as conn:
    with closing(conn.cursor()) as cursor:
        cursor.execute(sql)

Stack trace

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 270, in _close_connection
    self._dialect.do_close(connection)
  File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 549, in do_close
    dbapi_connection.close()
  File "/usr/local/lib/python3.7/site-packages/google/cloud/bigquery/dbapi/_helpers.py", line 258, in with_closed_check
    return method(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/google/cloud/bigquery/dbapi/connection.py", line 79, in close
    cursor_.close()
  File "/usr/local/lib/python3.7/site-packages/google/cloud/bigquery/dbapi/_helpers.py", line 257, in with_closed_check
    raise exc_class(exc_msg)
google.cloud.bigquery.dbapi.exceptions.ProgrammingError: Operating on a closed cursor.

Suggested fix

# google/cloud/bigquery/dbapi/connection.py
class Connection(object):
    ...
    def close(self):
        ...
        for cursor_ in self._cursors_created:
            if not cursor_._closed:
                cursor_.close()
@product-auto-label product-auto-label bot added the api: bigquery Issues related to the googleapis/python-bigquery API. label Jan 28, 2021
@betodealmeida betodealmeida changed the title Closing a connection tries to close closed cursors Closing a connection tries to close already closed cursors Jan 28, 2021
@plamut plamut added the type: question Request for information or clarification. Not an issue. label Jan 29, 2021
@plamut
Copy link
Contributor

plamut commented Jan 29, 2021

@betodealmeida Thanks for the report.

I can see where the issue is - the raise_on_closed() decorator makes all public methods throw if an instance is "closed", which includes the Cursor.close() method. Additionally, when closing a connection, the latter also attempts to automatically close all cursors that it created, thus it's not necessary to nest the closing() context managers:

with closing(engine.raw_connection()) as conn:
    conn.cursor().execute(sql)

However, there might be valid reasons to close a cursor early, and I agree that closing the connection at some later point should behave more gracefully, I'll fix that.

Edit: Ah, you already submitted a PR, even better, thanks!

@plamut plamut added priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. and removed type: question Request for information or clarification. Not an issue. labels Jan 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: bigquery Issues related to the googleapis/python-bigquery API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants