Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Closing a connection tries to close already closed cursors #497

Closed

Description

@betodealmeida

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()

Activity

  1. changed the title [-]Closing a connection tries to close closed cursors[/-] [+]Closing a connection tries to close already closed cursors[/+] on Jan 28, 2021
  2. added
    type: questionRequest for information or clarification. Not an issue.
    on Jan 29, 2021
  3. plamut commented on Jan 29, 2021

    @plamut
    Contributor

    @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!

  4. added
    priority: p2Moderately-important priority. Fix may not be included in next release.
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    and removed
    type: questionRequest for information or clarification. Not an issue.
    on Jan 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api: bigqueryIssues related to the googleapis/python-bigquery API.priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions