Commit 1d24f073 authored by Claude Paroz's avatar Claude Paroz
Browse files

Fixed #21255 -- Closed connections after management command ran

Thanks kabakov.as@gmail.com for the report, and Aymeric Augustin,
Simon Charette for the reviews.
parent bae404de
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ import django
from django.core import checks
from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style, no_style
from django.db import connections
from django.utils.deprecation import RemovedInDjango19Warning, RemovedInDjango20Warning
from django.utils.encoding import force_str

@@ -398,6 +399,8 @@ class BaseCommand(object):
            else:
                self.stderr.write('%s: %s' % (e.__class__.__name__, e))
            sys.exit(1)
        finally:
            connections.close_all()

    def execute(self, *args, **options):
        """
+8 −0
Original line number Diff line number Diff line
@@ -252,6 +252,14 @@ class ConnectionHandler(object):
    def all(self):
        return [self[alias] for alias in self]

    def close_all(self):
        for alias in self:
            try:
                connection = getattr(self._connections, alias)
            except AttributeError:
                continue
            connection.close()


class ConnectionRouter(object):
    def __init__(self, routers=None):
+3 −0
Original line number Diff line number Diff line
@@ -352,6 +352,9 @@ Logging
Management Commands
^^^^^^^^^^^^^^^^^^^

* Database connections are now always closed after a management command called
  from the command line has finished doing its job.

* :djadmin:`dumpdata` now has the option :djadminopt:`--output` which allows
  specifying the file to which the serialized data is written.

+13 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ from django.core.management import BaseCommand, CommandError, call_command, colo
from django.utils.encoding import force_text
from django.utils._os import npath, upath
from django.utils.six import StringIO
from django.test import LiveServerTestCase, TestCase, override_settings
from django.test import LiveServerTestCase, TestCase, mock, override_settings
from django.test.runner import DiscoverRunner


@@ -1581,6 +1581,18 @@ class CommandTypes(AdminScriptTestCase):
        with self.assertRaises(SystemExit):
            command.run_from_argv(['', ''])

    def test_run_from_argv_closes_connections(self):
        """
        A command called from the command line should close connections after
        being executed (#21255).
        """
        command = BaseCommand(stderr=StringIO())
        command.handle = lambda *args, **kwargs: args
        with mock.patch('django.core.management.base.connections') as mock_connections:
            command.run_from_argv(['', ''])
        # Test connections have been closed
        self.assertTrue(mock_connections.close_all.called)

    def test_noargs(self):
        "NoArg Commands can be executed"
        args = ['noargs_command']