Changeset 3768
- Timestamp:
- 09/17/06 14:12:04 (2 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/multiple-db-support/django/db/__init__.py
r3738 r3768 15 15 # singleton to represent the default connection in connections 16 16 class dummy(object): 17 def __repr__(self): 18 return self.__str__() 17 19 def __str__(self): 18 20 return '<default>' … … 29 31 30 32 31 def connect(settings ):33 def connect(settings, **kw): 32 34 """Connect to the database specified in settings. Returns a 33 35 ConnectionInfo on success, raises ImproperlyConfigured if the 34 36 settings don't specify a valid database connection. 35 37 """ 36 info = ConnectionInfo(settings) 37 38 # Register an event that closes the database connection 39 # when a Django request is finished. 40 dispatcher.connect(info.close, signal=signals.request_finished) 41 42 # Register an event that resets connection.queries 43 # when a Django request is started. 44 dispatcher.connect(info.reset_queries, signal=signals.request_started) 45 46 return info 38 return ConnectionInfo(settings, **kw) 47 39 48 40 … … 53 45 connection, and resetting the connection's query log. 54 46 """ 55 def __init__(self, settings=None): 47 def __init__(self, settings=None, **kw): 48 super(ConnectionInfo, self).__init__(**kw) 56 49 if settings is None: 57 50 from django.conf import settings … … 61 54 self.DatabaseError = self.backend.DatabaseError 62 55 56 # Register an event that closes the database connection 57 # when a Django request is finished. 58 dispatcher.connect(self.close, signal=signals.request_finished) 59 60 # Register an event that resets connection.queries 61 # when a Django request is started. 62 dispatcher.connect(self.reset_queries, signal=signals.request_started) 63 63 64 def __repr__(self): 64 65 return "Connection: %r (ENGINE=%s NAME=%s)" \ … … 115 116 self.connection.queries = [] 116 117 117 118 118 119 class LazyConnectionManager(object): 119 120 """Manages named connections lazily, instantiating them as … … 124 125 self.local.connections = {} 125 126 127 # Reset connections on request finish, to make sure each request can 128 # load the correct connections for its settings 129 dispatcher.connect(self.reset, signal=signals.request_finished) 130 126 131 def __iter__(self): 127 return self.local.connections.keys() 132 # Iterates only over *active* connections, not all possible 133 # connections 134 return iter(self.local.connections.keys()) 128 135 129 136 def __getattr__(self, attr): … … 178 185 return cnx[name] 179 186 187 def items(self): 188 # Iterates over *all possible* connections 189 items = [] 190 for key in self.keys(): 191 items.append((key, self[key])) 192 return items 193 194 def keys(self): 195 # Iterates over *all possible* connections 196 keys = [_default] 197 try: 198 keys.extend(settings.OTHER_DATABASES.keys()) 199 except AttributeError: 200 pass 201 return keys 202 180 203 def reset(self): 204 if not hasattr(self.local, 'connections'): 205 return 181 206 self.local.connections = {} 182 183 207 184 208 def model_connection_name(klass): 185 209 """Get the connection name that a model is configured to use, with the … … 262 286 def get_connection(self, instance): 263 287 return connections[model_connection_name(instance.model)] 264 288 265 289 def reset(self): 290 if not hasattr(self.local, 'cnx'): 291 return 266 292 self.local.cnx = {} 267 268 293 269 294 class LocalizingProxy: … … 278 303 self.__arg = arg 279 304 self.__kw = kw 305 306 # We need to clear out this thread's storage at the end of each 307 # request, in case new settings are loaded with the next 308 def reset(stor=storage, name=name): 309 if hasattr(stor, name): 310 delattr(stor, name) 311 dispatcher.connect(reset, signal=signals.request_finished) 280 312 281 313 def __getattr__(self, attr): … … 296 328 return 297 329 try: 298 print self.__storage, self.__name299 330 stor = getattr(self.__storage, self.__name) 300 331 except AttributeError: … … 302 333 setattr(self.__storage, self.__name, stor) 303 334 setattr(stor, attr, val) 304 335 305 336 306 337 # Create a manager for named connections … … 328 359 329 360 330 # Reset connections on request finish, to make sure each request can331 # load the correct connections for its settings332 dispatcher.connect(connections.reset, signal=signals.request_finished)333 334 335 361 # Register an event that rolls back all connections 336 362 # when a Django request has an exception. django/branches/multiple-db-support/django/test/utils.py
r3760 r3768 1 1 import sys, time 2 2 from django.conf import settings 3 4 3 from django.db import backend, connect, connection, connection_info, connections 5 4 from django.dispatch import dispatcher … … 95 94 96 95 # Fill OTHER_DATABASES with the TEST_DATABASES settings, 97 # and connect each named connection to the test database, using 98 # a separate connection instance for each (so, eg, transactions don't 99 # collide) 96 # and connect each named connection to the test database. 100 97 test_databases = {} 101 98 for db_name in settings.TEST_DATABASES: 102 if settings.DATABASE_ENGINE == 'sqlite3': 103 full_name = TEST_DATABASE_NAME 104 else: 105 full_name = TEST_DATABASE_NAME + db_name 106 db_st = {'DATABASE_NAME': full_name} 99 db_st = {'DATABASE_NAME': TEST_DATABASE_NAME} 107 100 if db_name in settings.TEST_DATABASE_MODELS: 108 101 db_st['MODELS'] = settings.TEST_DATABASE_MODELS.get(db_name, []) 109 102 test_databases[db_name] = db_st 110 connections[db_name] = connect(connection_info.settings)111 connections[db_name].connection.cursor() # Initialize it112 103 settings.OTHER_DATABASES = test_databases 113 104 114 105 def destroy_test_db(old_database_name, old_databases, verbosity=1): 115 106 # Unless we're using SQLite, remove the test database to clean up after … … 119 110 if verbosity >= 1: 120 111 print "Destroying test database..." 112 113 connection.close() 121 114 for cnx in connections.keys(): 122 115 connections[cnx].close() 116 connections.reset() 117 123 118 TEST_DATABASE_NAME = settings.DATABASE_NAME 119 if verbosity >= 2: 120 print "Closed connections to %s" % TEST_DATABASE_NAME 124 121 settings.DATABASE_NAME = old_database_name 125 122 126 123 if settings.DATABASE_ENGINE != "sqlite3": 127 124 settings.OTHER_DATABASES = old_databases 128 125 for cnx in connections.keys(): 129 connections[cnx].connection.cursor() 126 try: 127 connections[cnx].connection.cursor() 128 except (KeyboardInterrupt, SystemExit): 129 raise 130 except: 131 pass 130 132 cursor = connection.cursor() 131 133 _set_autocommit(connection) django/branches/multiple-db-support/tests/modeltests/multiple_databases/models.py
r3760 r3768 85 85 Connection: ... 86 86 87 # Let's see what connections are available.The default connection is 88 # in there, but let's ignore it 89 90 >>> non_default = connections.keys() 91 >>> non_default.remove(_default) 92 >>> non_default.sort() 93 >>> non_default 94 ['_a', '_b'] 87 # Let's see what connections are available. The default connection is always 88 # included in connections as well, and may be accessed as connections[_default]. 89 90 >>> connection_names = connections.keys() 91 >>> connection_names.sort() 92 >>> connection_names 93 [<default>, '_a', '_b'] 95 94 96 95 # Invalid connection names raise ImproperlyConfigured 96 97 97 >>> connections['bad'] 98 98 Traceback (most recent call last): … … 100 100 ImproperlyConfigured: No database connection 'bad' has been configured 101 101 102 # Models can access their connections through their managers 102 # The model_connection_name() function will tell you the name of the 103 # connection that a model is configured to use. 104 103 105 >>> model_connection_name(Artist) 104 106 '_a' … … 116 118 >>> list(artists) 117 119 [<Artist: Paul Klee>] 120 121 # Models can access their connections through the db property of their 122 # default manager. 123 124 >>> paul = _[0] 125 >>> Artist.objects.db 126 Connection: ... (ENGINE=... NAME=...) 127 >>> paul._default_manager.db 128 Connection: ... (ENGINE=... NAME=...) 118 129 119 130 # When transactions are not managed, model save will commit only
