Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#33160 closed Bug (fixed)

DatabaseWrapper._nodb_cursor() raises wrong warnings in case of errors from queries on PostgreSQL.

Reported by: Daniel Hahler Owned by: Daniel Hahler
Component: Database layer (models, ORM) Version: 3.2
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Daniel Hahler)

{{_nodb_cursor}} might cause a confusing/wrong warning, e.g. via {{teardown_database}}:

  [35] …/Vcs/django/django/test/utils.py(313)teardown_databases()
       connection.creation.destroy_test_db(old_name, verbosity, keepdb)
  [36] …/Vcs/django/django/db/backends/base/creation.py(282)destroy_test_db()
       self._destroy_test_db(test_database_name, verbosity)
  [37] …/Vcs/django/django/db/backends/base/creation.py(298)_destroy_test_db()
       cursor.execute("DROP DATABASE %s"
  [38] /usr/lib/python3.9/contextlib.py(137)__exit__()
       self.gen.throw(typ, value, traceback)
> [39] …/Vcs/django/django/db/backends/postgresql/base.py(306)_nodb_cursor()
       warnings.warn(
(Pdb++) l
301                 with super()._nodb_cursor() as cursor:
302                     yield cursor
303             except (Database.DatabaseError, WrappedDatabaseError) as exc:
304                 e = exc
305                 __import__('pdb').set_trace()
306  ->             warnings.warn(
307                     "Normally Django will use a connection to the 'postgres' database "
308                     "to avoid running initialization queries against the production "
309                     "database when it's not needed (for example, when running tests). "
310                     "Django was unable to create a connection to the 'postgres' database "
311                     "and will use the first PostgreSQL database instead.",
(Pdb++) e
OperationalError('database "test_foo" is being accessed by other users\nDETAIL:  There is 1 other session using the database.\n')

As you can see there is another issue this will (partly) swallow/hide then, apart from the message being just wrong: it is not the connection that failed, but a query in there:

[37] > …/django/django/db/backends/base/creation.py(298)_destroy_test_db(), 4 frames hidden

289         def _destroy_test_db(self, test_database_name, verbosity):
290             """
291             Internal implementation - remove the test db tables.
292             """
293             # Remove the test database to clean up after
294             # ourselves. Connect to the previous database (not the test database)
295             # to do so, because it's not allowed to delete a database while being
296             # connected to it.
297             with self._nodb_cursor() as cursor:
298  ->             cursor.execute("DROP DATABASE %s"
299                                % self.connection.ops.quote_name(test_database_name))

Only {{connect()} should get wrapped/handled in {{_nodb_cursor}} probably (in terms of adding the warning), which could be achieved by handling specific exceptions only, or re-raising it in case a {{cursor}} was used (i.e. it could connect).

Possible fix: https://github.com/django/django/pull/14918

Change History (6)

comment:1 by Daniel Hahler, 3 years ago

Has patch: set

comment:2 by Daniel Hahler, 3 years ago

Description: modified (diff)

comment:3 by Mariusz Felisiak, 3 years ago

Needs tests: set
Owner: changed from nobody to Daniel Hahler
Status: newassigned
Summary: postgresql DatabaseWrapper._nodb_cursor causes confusing/wrong "Django was unable to create a connection to the 'postgres' database" warning in case of errors from queriesDatabaseWrapper._nodb_cursor() raises wrong warnings in case of errors from queries on PostgreSQL.
Triage Stage: UnreviewedAccepted

Thanks for the report.

comment:4 by Daniel Hahler, 3 years ago

Needs tests: unset

comment:5 by GitHub <noreply@…>, 3 years ago

Resolution: fixed
Status: assignedclosed

In 98c8bf1:

Fixed #33160 -- Avoided suppressing query errors in _nodb_cursor() on PostgreSQL.

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 3 years ago

In 81bb0ae2:

[4.0.x] Fixed #33160 -- Avoided suppressing query errors in _nodb_cursor() on PostgreSQL.

Backport of 98c8bf1ceeab5c68751c83555f82cff1a9120a67 from main

Note: See TracTickets for help on using tickets.
Back to Top