﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
33160	"postgresql DatabaseWrapper._nodb_cursor causes confusing/wrong ""Django was unable to create a connection to the 'postgres' database"" warning in case of errors from queries"	Daniel Hahler	nobody	"{{_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)."	Bug	new	Database layer (models, ORM)	3.2	Normal				Unreviewed	0	0	0	0	0	0
