diff --git a/django/db/backends/base/client.py b/django/db/backends/base/client.py index 339f1e863c..8aca821fd2 100644 --- a/django/db/backends/base/client.py +++ b/django/db/backends/base/client.py @@ -21,6 +21,5 @@ class BaseDatabaseClient: def runshell(self, parameters): args, env = self.settings_to_cmd_args_env(self.connection.settings_dict, parameters) - if env: - env = {**os.environ, **env} + env = {**os.environ, **env} if env else None subprocess.run(args, env=env, check=True) diff --git a/django/db/backends/postgresql/client.py b/django/db/backends/postgresql/client.py index 3effab65a8..0effcc44e6 100644 --- a/django/db/backends/postgresql/client.py +++ b/django/db/backends/postgresql/client.py @@ -51,7 +51,7 @@ class DatabaseClient(BaseDatabaseClient): env['PGSSLKEY'] = str(sslkey) if passfile: env['PGPASSFILE'] = str(passfile) - return args, env + return args, (env or None) def runshell(self, parameters): sigint_handler = signal.getsignal(signal.SIGINT) diff --git a/docs/releases/3.2.1.txt b/docs/releases/3.2.1.txt index 83d317bc7e..1c8776a0bf 100644 --- a/docs/releases/3.2.1.txt +++ b/docs/releases/3.2.1.txt @@ -65,3 +65,6 @@ Bugfixes admin changelist now uses ``Exists()`` instead ``QuerySet.distinct()`` because calling ``delete()`` after ``distinct()`` is not allowed in Django 3.2 to address a data loss possibility. + +* Fixed a regression in Django 3.2 where the calling process environment would + not be passed to the ``dbshell`` command on PostgreSQL (:ticket:`32687`). diff --git a/tests/backends/base/test_client.py b/tests/backends/base/test_client.py index 4573bbe97b..d9e5cc8883 100644 --- a/tests/backends/base/test_client.py +++ b/tests/backends/base/test_client.py @@ -1,3 +1,5 @@ +from unittest import mock + from django.db import connection from django.db.backends.base.client import BaseDatabaseClient from django.test import SimpleTestCase @@ -14,3 +16,15 @@ class SimpleDatabaseClientTests(SimpleTestCase): ) with self.assertRaisesMessage(NotImplementedError, msg): self.client.settings_to_cmd_args_env(None, None) + + def test_runshell_use_environ(self): + for env in [None, {}]: + with self.subTest(env=env): + with mock.patch('subprocess.run') as run: + with mock.patch.object( + BaseDatabaseClient, + 'settings_to_cmd_args_env', + return_value=([], env), + ): + self.client.runshell(None) + run.assert_called_once_with([], env=None, check=True) diff --git a/tests/dbshell/test_postgresql.py b/tests/dbshell/test_postgresql.py index a96acac6f1..6aaf6c8f77 100644 --- a/tests/dbshell/test_postgresql.py +++ b/tests/dbshell/test_postgresql.py @@ -39,7 +39,7 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase): 'PORT': '444', }), ( ['psql', '-U', 'someuser', '-h', 'somehost', '-p', '444', 'dbname'], - {}, + None, ) ) @@ -134,7 +134,7 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase): def test_parameters(self): self.assertEqual( self.settings_to_cmd_args_env({'NAME': 'dbname'}, ['--help']), - (['psql', 'dbname', '--help'], {}), + (['psql', 'dbname', '--help'], None), ) @skipUnless(connection.vendor == 'postgresql', 'Requires a PostgreSQL connection')