Ticket #17258: 17258.thread-local-connections.2.diff
File 17258.thread-local-connections.2.diff, 6.0 KB (added by , 13 years ago) |
---|
-
django/db/__init__.py
diff --git a/django/db/__init__.py b/django/db/__init__.py index 8395468..d589338 100644
a b 1 from threading import local 1 2 from django.conf import settings 2 3 from django.core import signals 3 4 from django.core.exceptions import ImproperlyConfigured … … router = ConnectionRouter(settings.DATABASE_ROUTERS) 22 23 # we manually create the dictionary from the settings, passing only the 23 24 # settings that the database backends care about. Note that TIME_ZONE is used 24 25 # by the PostgreSQL backends. 25 # we load all these up for backwards compatibility, you should use26 # We load all these up for backwards compatibility, you should use 26 27 # connections['default'] instead. 27 connection = connections[DEFAULT_DB_ALIAS] 28 class DefaultConnectionProxy(object): 29 """ 30 Proxy for the thread-local default connection. 31 """ 32 def __getattr__(self, item): 33 return getattr(connections[DEFAULT_DB_ALIAS], item) 34 35 def __setattr__(self, name, value): 36 return setattr(connections[DEFAULT_DB_ALIAS], name, value) 37 38 connection = DefaultConnectionProxy() 28 39 backend = load_backend(connection.settings_dict['ENGINE']) 29 40 30 41 # Register an event that closes the database connection -
django/db/backends/__init__.py
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index f2bde84..0f4fc31 100644
a b try: 2 2 import thread 3 3 except ImportError: 4 4 import dummy_thread as thread 5 from threading import local6 5 from contextlib import contextmanager 7 6 8 7 from django.conf import settings … … from django.utils.importlib import import_module 13 12 from django.utils.timezone import is_aware 14 13 15 14 16 class BaseDatabaseWrapper( local):15 class BaseDatabaseWrapper(object): 17 16 """ 18 17 Represents a database connection. 19 18 """ -
django/db/utils.py
diff --git a/django/db/utils.py b/django/db/utils.py index f0c13e3..41ad6df 100644
a b 1 1 import os 2 from threading import local 2 3 3 4 from django.conf import settings 4 5 from django.core.exceptions import ImproperlyConfigured … … class ConnectionDoesNotExist(Exception): 50 51 class ConnectionHandler(object): 51 52 def __init__(self, databases): 52 53 self.databases = databases 53 self._connections = {}54 self._connections = local() 54 55 55 56 def ensure_defaults(self, alias): 56 57 """ … … class ConnectionHandler(object): 73 74 conn.setdefault(setting, None) 74 75 75 76 def __getitem__(self, alias): 76 if alias in self._connections:77 return self._connections[alias]77 if hasattr(self._connections, alias): 78 return getattr(self._connections, alias) 78 79 79 80 self.ensure_defaults(alias) 80 81 db = self.databases[alias] 81 82 backend = load_backend(db['ENGINE']) 82 83 conn = backend.DatabaseWrapper(db, alias) 83 se lf._connections[alias] = conn84 setattr(self._connections, alias, conn) 84 85 return conn 85 86 87 def __setitem__(self, key, value): 88 setattr(self._connections, key, value) 89 86 90 def __iter__(self): 87 91 return iter(self.databases) 88 92 -
tests/regressiontests/backends/tests.py
diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py index 936f010..e569df9 100644
a b 3 3 from __future__ import with_statement, absolute_import 4 4 5 5 import datetime 6 import threading 6 7 7 8 from django.conf import settings 8 9 from django.core.management.color import no_style … … class ConnectionCreatedSignalTest(TestCase): 283 284 connection_created.connect(receiver) 284 285 connection.close() 285 286 cursor = connection.cursor() 286 self.assertTrue(data["connection"] isconnection)287 self.assertTrue(data["connection"].connection is connection.connection) 287 288 288 289 connection_created.disconnect(receiver) 289 290 data.clear() … … class FkConstraintsTests(TransactionTestCase): 446 447 connection.check_constraints() 447 448 finally: 448 449 transaction.rollback() 450 451 class ThreadTests(TestCase): 452 453 def test_default_connection_thread_local(self): 454 """ 455 Ensure that the default connection (i.e. django.db.connection) is 456 different for each thread. 457 Refs #17258. 458 """ 459 connections_set = set() 460 connection.cursor() 461 connections_set.add(connection.connection) 462 def runner(): 463 from django.db import connection 464 connection.cursor() 465 connections_set.add(connection.connection) 466 for x in xrange(2): 467 t = threading.Thread(target=runner) 468 t.start() 469 t.join() 470 self.assertEquals(len(connections_set), 3) 471 # Finish by closing the connections opened by the other threads (the 472 # connection opened in the main thread will automatically be closed on 473 # teardown). 474 for conn in connections_set: 475 if conn != connection.connection: 476 conn.close() 477 478 def test_connections_thread_local(self): 479 """ 480 Ensure that the connections are different for each thread. 481 Refs #17258. 482 """ 483 connections_set = set() 484 for conn in connections.all(): 485 connections_set.add(conn) 486 def runner(): 487 from django.db import connections 488 for conn in connections.all(): 489 connections_set.add(conn) 490 for x in xrange(2): 491 t = threading.Thread(target=runner) 492 t.start() 493 t.join() 494 self.assertEquals(len(connections_set), 6) 495 # Finish by closing the connections opened by the other threads (the 496 # connection opened in the main thread will automatically be closed on 497 # teardown). 498 for conn in connections_set: 499 if conn != connection: 500 conn.close() 501 No newline at end of file