mirror of https://github.com/django/django.git
Fixed #21255 -- Closed connections after management command ran
Thanks kabakov.as@gmail.com for the report, and Aymeric Augustin, Simon Charette for the reviews.
This commit is contained in:
parent
bae404dea3
commit
1d24f073e6
|
@ -18,6 +18,7 @@ import django
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.management.color import color_style, no_style
|
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.deprecation import RemovedInDjango19Warning, RemovedInDjango20Warning
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
|
||||||
|
@ -398,6 +399,8 @@ class BaseCommand(object):
|
||||||
else:
|
else:
|
||||||
self.stderr.write('%s: %s' % (e.__class__.__name__, e))
|
self.stderr.write('%s: %s' % (e.__class__.__name__, e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
finally:
|
||||||
|
connections.close_all()
|
||||||
|
|
||||||
def execute(self, *args, **options):
|
def execute(self, *args, **options):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -252,6 +252,14 @@ class ConnectionHandler(object):
|
||||||
def all(self):
|
def all(self):
|
||||||
return [self[alias] for alias in 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):
|
class ConnectionRouter(object):
|
||||||
def __init__(self, routers=None):
|
def __init__(self, routers=None):
|
||||||
|
|
|
@ -352,6 +352,9 @@ Logging
|
||||||
Management Commands
|
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
|
* :djadmin:`dumpdata` now has the option :djadminopt:`--output` which allows
|
||||||
specifying the file to which the serialized data is written.
|
specifying the file to which the serialized data is written.
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ from django.core.management import BaseCommand, CommandError, call_command, colo
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils._os import npath, upath
|
from django.utils._os import npath, upath
|
||||||
from django.utils.six import StringIO
|
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
|
from django.test.runner import DiscoverRunner
|
||||||
|
|
||||||
|
|
||||||
|
@ -1581,6 +1581,18 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
with self.assertRaises(SystemExit):
|
with self.assertRaises(SystemExit):
|
||||||
command.run_from_argv(['', ''])
|
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):
|
def test_noargs(self):
|
||||||
"NoArg Commands can be executed"
|
"NoArg Commands can be executed"
|
||||||
args = ['noargs_command']
|
args = ['noargs_command']
|
||||||
|
|
Loading…
Reference in New Issue