MultipleDatabaseSupport: p4.diff
File p4.diff, 36.2 KB (added by , 18 years ago) |
---|
-
django/db/models/base.py
=== django/db/models/base.py ==================================================================
38 38 new_class._meta.parents.extend(base._meta.parents) 39 39 40 40 model_module = sys.modules[new_class.__module__] 41 41 42 42 if getattr(new_class._meta, 'app_label', None) is None: 43 43 # Figure out the app_label by looking one level up. 44 44 # For 'django.contrib.sites.models', this would be 'sites'. … … 149 149 dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self) 150 150 151 151 non_pks = [f for f in self._meta.fields if not f.primary_key] 152 cursor = connection.cursor()152 cursor = self._meta.connection.cursor() 153 153 154 154 # First, try an UPDATE. If that doesn't update anything, do an INSERT. 155 155 pk_val = self._get_pk_val() … … 362 362 rel = rel_field.rel.to 363 363 m2m_table = rel_field.m2m_db_table() 364 364 this_id = self._get_pk_val() 365 cursor = connection.cursor()365 cursor = self._meta.connection.cursor() 366 366 cursor.execute("DELETE FROM %s WHERE %s = %%s" % \ 367 367 (backend.quote_name(m2m_table), 368 368 backend.quote_name(rel_field.m2m_column_name())), [this_id]) … … 380 380 # ORDERING METHODS ######################### 381 381 382 382 def method_set_order(ordered_obj, self, id_list): 383 connection_info = ordered_obj.connection_info 384 connection = info.connection 385 backend = info.backend 386 383 387 cursor = connection.cursor() 384 388 # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s" 385 389 sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \ … … 391 395 transaction.commit_unless_managed() 392 396 393 397 def method_get_order(ordered_obj, self): 398 connection_info = ordered_obj.connection_info 399 connection = info.connection 400 backend = info.backend 394 401 cursor = connection.cursor() 395 402 # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order" 396 403 sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \ -
django/db/models/manager.py
=== django/db/models/manager.py ==================================================================
95 95 def values(self, *args, **kwargs): 96 96 return self.get_query_set().values(*args, **kwargs) 97 97 98 ####################### 99 # SCHEMA MANIPULATION # 100 ####################### 101 102 def install(self, initial_data=False): 103 """Install my model's table, indexes and (if requested) initial data. 104 105 Returns a 3-tuple of the model and lists of statements executed and 106 statements pending. Pending statements are those that could 107 not yet be executed, such as foreign key constraints for 108 tables that don't exist at install time. 109 """ 110 creator = self.model._meta.connection_info.get_creation_module() 111 create, pending = creator.get_create_table(self.model) 112 create += creator.get_create_indexes(self.model) 113 if initial_data: 114 create += creator.get_initialdata(self.model) 115 116 executed = [] 117 for statement in create: 118 statement.execute() 119 return (self.model, create, pending) 120 121 def load_initial_data(self): 122 """Load initial data for my model into the database.""" 123 pass 124 125 def drop(self): 126 """Drop my model's table.""" 127 pass 128 129 # Future... 130 131 def add_column(self, column): 132 """Add a column to my model's table""" 133 pass 134 135 def drop_column(self, column): 136 """Drop a column from my model's table""" 137 pass 138 139 98 140 class ManagerDescriptor(object): 99 141 # This class ensures managers aren't accessible via model instances. 100 142 # For example, Poll.objects works, but poll_obj.objects raises AttributeError. -
django/db/models/options.py
=== django/db/models/options.py ==================================================================
1 1 from django.conf import settings 2 from django.db import connection_info, connections 2 3 from django.db.models.related import RelatedObject 3 4 from django.db.models.fields.related import ManyToManyRel 4 5 from django.db.models.fields import AutoField, FieldDoesNotExist … … 11 12 # Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces". 12 13 get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip() 13 14 14 DEFAULT_NAMES = ('verbose_name', 'db_ table', 'ordering',15 DEFAULT_NAMES = ('verbose_name', 'db_connection', 'db_table', 'ordering', 15 16 'unique_together', 'permissions', 'get_latest_by', 16 17 'order_with_respect_to', 'app_label') 17 18 … … 20 21 self.fields, self.many_to_many = [], [] 21 22 self.module_name, self.verbose_name = None, None 22 23 self.verbose_name_plural = None 24 self.db_connection = None 23 25 self.db_table = '' 24 26 self.ordering = [] 25 27 self.unique_together = [] … … 56 58 raise TypeError, "'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()) 57 59 else: 58 60 self.verbose_name_plural = self.verbose_name + 's' 61 # 59 62 del self.meta 60 63 61 64 def _prepare(self, model): … … 88 91 def __repr__(self): 89 92 return '<Options for %s>' % self.object_name 90 93 94 def get_connection_info(self): 95 if self.db_connection: 96 return connections[self.db_connection] 97 return connection_info 98 connection_info = property(get_connection_info) 99 100 def get_connection(self): 101 """Get the database connection for this object's model""" 102 return self.get_connection_info().connection 103 connection = property(get_connection) 104 91 105 def get_field(self, name, many_to_many=True): 92 106 "Returns the requested field by name. Raises FieldDoesNotExist on error." 93 107 to_search = many_to_many and (self.fields + self.many_to_many) or self.fields -
django/db/models/loading.py
=== django/db/models/loading.py ==================================================================
8 8 _app_list = None # Cache of installed apps. 9 9 _app_models = {} # Dictionary of models against app label 10 10 # Each value is a dictionary of model name: model class 11 11 _app_model_order = {} # Dictionary of models against app label 12 # Each value is a list of model names, in the order in 13 # which the models were created 12 14 def get_apps(): 13 15 "Returns a list of all installed modules that contain models." 14 16 global _app_list … … 35 37 return __import__(app_name, '', '', ['models']).models 36 38 raise ImproperlyConfigured, "App with label %s could not be found" % app_label 37 39 38 def get_models(app_mod=None ):40 def get_models(app_mod=None, creation_order=False): 39 41 """ 40 42 Given a module containing models, returns a list of the models. Otherwise 41 returns a list of all installed models. 43 returns a list of all installed models. In either case, if creation_order 44 is true, return the models sorted into the same order in which they 45 were created. 42 46 """ 43 47 app_list = get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish. 44 48 if app_mod: 45 return _app_models.get(app_mod.__name__.split('.')[-2], {}).values() 49 app_label = app_mod.__name__.split('.')[-2] 50 app_models = _app_models.get(app_label, {}) 51 if creation_order: 52 return [ app_models[name] 53 for name in _app_model_order.get(app_label, []) ] 54 return app_models.values() 46 55 else: 47 56 model_list = [] 48 57 for app_mod in app_list: … … 75 84 model_name = model._meta.object_name.lower() 76 85 model_dict = _app_models.setdefault(app_label, {}) 77 86 model_dict[model_name] = model 87 model_list = _app_model_order.setdefault(app_label, []) 88 model_list.append(model_name) -
django/db/models/query.py
=== django/db/models/query.py ==================================================================
1 from django.db import backend, connection, transaction1 from django.db import backend, connection, connections, transaction 2 2 from django.db.models.fields import DateField, FieldDoesNotExist 3 3 from django.db.models import signals 4 4 from django.dispatch import dispatcher … … 158 158 # undefined, so we convert it to a list of tuples. 159 159 extra_select = self._select.items() 160 160 161 cursor = connection.cursor()161 cursor = self.model._meta.connection.cursor() 162 162 select, sql, params = self._get_sql_clause() 163 163 cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) 164 164 fill_cache = self._select_related … … 178 178 179 179 def count(self): 180 180 "Performs a SELECT COUNT() and returns the number of records as an integer." 181 182 info = self.model._meta.connection_info 183 backend = info.backend 184 connection = info.connection 185 181 186 counter = self._clone() 182 187 counter._order_by = () 183 188 counter._offset = None … … 505 510 columns = [f.column for f in self.model._meta.fields] 506 511 field_names = [f.attname for f in self.model._meta.fields] 507 512 513 info = self.model._meta.connection_info 514 backend = info.backend 515 connection = info.connection 508 516 cursor = connection.cursor() 509 517 select, sql, params = self._get_sql_clause() 510 518 select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] … … 524 532 class DateQuerySet(QuerySet): 525 533 def iterator(self): 526 534 from django.db.backends.util import typecast_timestamp 535 536 info = self.model._meta.connection_info 537 backend = info.backend 538 connection = info.connection 539 527 540 self._order_by = () # Clear this because it'll mess things up otherwise. 528 541 if self._field.null: 529 542 self._where.append('%s.%s IS NOT NULL' % \ … … 616 629 where2 = ['(NOT (%s))' % " AND ".join(where)] 617 630 return tables, joins, where2, params 618 631 619 def get_where_clause(lookup_type, table_prefix, field_name, value): 632 def get_where_clause(opts, lookup_type, table_prefix, field_name, value): 633 backend = opts.connection_info.backend 634 620 635 if table_prefix.endswith('.'): 621 636 table_prefix = backend.quote_name(table_prefix[:-1])+'.' 622 637 field_name = backend.quote_name(field_name) … … 745 760 intermediate_table = None 746 761 join_required = False 747 762 763 info = current_opts.connection_info 764 backend = info.backend 765 connection = info.connection 766 748 767 name = path.pop(0) 749 768 # Has the primary key been requested? If so, expand it out 750 769 # to be the name of the current class' primary key … … 872 891 else: 873 892 column = field.column 874 893 875 where.append(get_where_clause(c lause, current_table + '.', column, value))894 where.append(get_where_clause(current_opts, clause, current_table + '.', column, value)) 876 895 params.extend(field.get_db_prep_lookup(clause, value)) 877 896 878 897 return tables, joins, where, params … … 882 901 ordered_classes = seen_objs.keys() 883 902 ordered_classes.reverse() 884 903 885 cursor = connection.cursor()886 904 887 905 for cls in ordered_classes: 906 907 info = cls._meta.connection_info 908 backend = info.backend 909 connection = info.connection 910 cursor = connection.cursor() 911 888 912 seen_objs[cls] = seen_objs[cls].items() 889 913 seen_objs[cls].sort() 890 914 … … 919 943 920 944 # Now delete the actual data 921 945 for cls in ordered_classes: 946 947 info = cls._meta.connection_info 948 backend = info.backend 949 connection = info.connection 950 cursor = connection.cursor() 951 922 952 seen_objs[cls].reverse() 923 953 pk_list = [pk for pk,instance in seen_objs[cls]] 924 954 for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): -
django/db/__init__.py
=== django/db/__init__.py ==================================================================
1 from django.conf import settings 1 from django.conf import settings, UserSettingsHolder 2 2 from django.core import signals 3 from django.core.exceptions import ImproperlyConfigured 3 4 from django.dispatch import dispatcher 4 5 5 6 __all__ = ('backend', 'connection', 'DatabaseError') … … 7 8 if not settings.DATABASE_ENGINE: 8 9 settings.DATABASE_ENGINE = 'dummy' 9 10 10 try: 11 backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, '', '', ['']) 12 except ImportError, e: 13 # The database backend wasn't found. Display a helpful error message 14 # listing all possible database backends. 15 from django.core.exceptions import ImproperlyConfigured 16 import os 17 backend_dir = os.path.join(__path__[0], 'backends') 18 available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')] 19 available_backends.sort() 20 if settings.DATABASE_ENGINE not in available_backends: 21 raise ImproperlyConfigured, "%r isn't an available database backend. vailable options are: %s" % \ 22 (settings.DATABASE_ENGINE, ", ".join(map(repr, available_backends))) 23 else: 24 raise # If there's some other error, this must be an error in Django itself. 11 class ConnectionInfo(object): 12 """Encapsulates all information about a db connection: 13 - connection 14 - DatabaseError 15 - backend 16 - get_introspection_module 17 - get_creation_module 18 - runshell 19 """ 20 def __init__(self, connection, DatabaseError, backend, 21 get_introspection_module, get_creation_module, runshell): 22 self.connection = connection 23 self.DatabaseError = DatabaseError 24 self.backend = backend 25 self.get_introspection_module = get_introspection_module 26 self.get_creation_module = get_creation_module 27 self.runshell = runshell 25 28 26 get_introspection_module = lambda: __import__('django.db.backends.%s.introspection' % settings.DATABASE_ENGINE, '', '', ['']) 27 get_creation_module = lambda: __import__('django.db.backends.%s.creation' % settings.DATABASE_ENGINE, '', '', ['']) 28 runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, '', '', ['']).runshell() 29 def __repr__(self): 30 return "Connection: %r (ENGINE=%s NAME=%s)" \ 31 % (self.connection, 32 self.connection.settings.DATABASE_ENGINE, 33 self.connection.settings.DATABASE_NAME) 29 34 30 connection = backend.DatabaseWrapper() 31 DatabaseError = backend.DatabaseError 35 def connect(settings=settings): 36 """Connect to the database specified in the given settings. 37 """ 38 try: 39 backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, '', '', ['']) 40 except ImportError, e: 41 # The database backend wasn't found. Display a helpful error message 42 # listing all possible database backends. 43 import os 44 backend_dir = os.path.join(__path__[0], 'backends') 45 available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')] 46 available_backends.sort() 47 if settings.DATABASE_ENGINE not in available_backends: 48 raise ImproperlyConfigured, "%r isn't an available database backend. vailable options are: %s" % \ 49 (settings.DATABASE_ENGINE, ", ".join(map(repr, available_backends))) 50 else: 51 raise # If there's some other error, this must be an error in Django itself. 32 52 33 # Register an event that closes the database connection34 # when a Django request is finished.35 dispatcher.connect(connection.close, signal=signals.request_finished)36 53 54 get_introspection_module = lambda: __import__('django.db.backends.%s.introspection' % settings.DATABASE_ENGINE, '', '', ['']) 55 get_creation_module = lambda: __import__('django.db.backends.%s.creation' % settings.DATABASE_ENGINE, '', '', ['']) 56 runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, '', '', ['']).runshell() 57 58 connection = backend.DatabaseWrapper(settings) 59 DatabaseError = backend.DatabaseError 60 61 return ConnectionInfo(connection, DatabaseError, backend, 62 get_introspection_module, get_creation_module, 63 runshell) 64 65 connection_info = connect(settings) 66 67 # backwards compatibility 68 (connection, DatabaseError, backend, get_introspection_module, 69 get_creation_module, runshell) = (connection_info.connection, 70 connection_info.DatabaseError, 71 connection_info.backend, 72 connection_info.get_introspection_module, 73 connection_info.get_creation_module, 74 connection_info.runshell) 75 76 77 class LazyConnectionManager(object): 78 """Manages named connections lazily, instantiating them as 79 they are requested. 80 """ 81 82 def __init__(self): 83 self._connections = {} 84 85 def __getitem__(self, k): 86 try: 87 return self._connections[k] 88 except KeyError: 89 try: 90 self.connect(k) 91 return self._connections[k] 92 except KeyError: 93 raise ImproperlyConfigured, \ 94 "No database connection '%s' has been configured" % k 95 96 def connect(self, name): 97 from django.conf import settings 98 try: 99 database = settings.DATABASES[name] 100 try: 101 database.DATABASE_ENGINE 102 except AttributeError: 103 # assume its a dict and convert to settings instance 104 holder = UserSettingsHolder(settings) 105 for k, v in database.items(): 106 setattr(holder, k, v) 107 database = holder 108 settings.DATABASES[name] = database 109 self._connections[name] = connect(database) 110 except AttributeError: 111 # no named connections to set up 112 pass 113 114 connections = LazyConnectionManager() 115 37 116 # Register an event that resets connection.queries 38 117 # when a Django request is started. 39 def reset_queries( ):118 def reset_queries(connection=connection): 40 119 connection.queries = [] 41 120 dispatcher.connect(reset_queries, signal=signals.request_started) 42 121 … … 46 125 from django.db import transaction 47 126 transaction.rollback_unless_managed() 48 127 dispatcher.connect(_rollback_on_exception, signal=signals.got_request_exception) 128 129 # Register an event that closes the database connection 130 # when a Django request is finished. 131 dispatcher.connect(connection.close, signal=signals.request_finished) 132 -
django/db/backends/postgresql/base.py
=== django/db/backends/postgresql/base.py ==================================================================
21 21 from django.utils._threading_local import local 22 22 23 23 class DatabaseWrapper(local): 24 def __init__(self): 24 def __init__(self, settings): 25 self.settings = settings 25 26 self.connection = None 26 27 self.queries = [] 27 28 28 29 def cursor(self): 29 from django.conf importsettings30 settings = self.settings 30 31 if self.connection is None: 31 32 if settings.DATABASE_NAME == '': 32 33 from django.core.exceptions import ImproperlyConfigured -
django/db/backends/postgresql/creation.py
=== django/db/backends/postgresql/creation.py ==================================================================
1 from django.db.backends.ansi.creation import SchemaBuilder 2 1 3 # This dictionary maps Field objects to their associated PostgreSQL column 2 4 # types, as strings. Column-type strings can contain format strings; they'll 3 5 # be interpolated against the values of Field.__dict__ before being output. … … 28 30 'URLField': 'varchar(200)', 29 31 'USStateField': 'varchar(2)', 30 32 } 33 34 _builder = SchemaBuilder() 35 get_create_table = _builder.get_create_table 36 get_create_indexes = _builder.get_create_indexes 37 get_initialdata = _builder.get_initialdata -
django/db/backends/sqlite3/base.py
=== django/db/backends/sqlite3/base.py ==================================================================
34 34 from django.utils._threading_local import local 35 35 36 36 class DatabaseWrapper(local): 37 def __init__(self): 37 def __init__(self, settings): 38 self.settings = settings 38 39 self.connection = None 39 40 self.queries = [] 40 41 41 42 def cursor(self): 42 from django.conf importsettings43 settings = self.settings 43 44 if self.connection is None: 44 45 self.connection = Database.connect(settings.DATABASE_NAME, 45 46 detect_types=Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES) -
django/db/backends/sqlite3/creation.py
=== django/db/backends/sqlite3/creation.py ==================================================================
1 from django.db.backends.ansi.creation import SchemaBuilder 2 1 3 # SQLite doesn't actually support most of these types, but it "does the right 2 4 # thing" given more verbose field definitions, so leave them as is so that 3 5 # schema inspection is more useful. … … 27 29 'URLField': 'varchar(200)', 28 30 'USStateField': 'varchar(2)', 29 31 } 32 33 _builder = SchemaBuilder() 34 get_create_table = _builder.get_create_table 35 get_create_indexes = _builder.get_create_indexes 36 get_initialdata = _builder.get_initialdata -
django/db/backends/ansi/__init__.py
=== django/db/backends/ansi/__init__.py ==================================================================
1 pass -
django/db/backends/ansi/creation.py
=== django/db/backends/ansi/creation.py ==================================================================
1 """ANSISQL schema manipulation functions and classes 2 """ 3 from django.db import models 4 5 # FIXME correct handling of styles, 6 # allow style object to be passed in 7 class dummy: 8 def __getattr__(self, attr): 9 return lambda x: x 10 11 class BoundStatement(object): 12 def __init__(self, sql, connection): 13 self.sql = sql 14 self.connection = connection 15 16 def execute(self): 17 cursor = self.connection.cursor() 18 cursor.execute(self.sql) 19 20 def __repr__(self): 21 return "BoundStatement(%r)" % self.sql 22 23 def __str__(self): 24 return self.sql 25 26 def __eq__(self, other): 27 return self.sql == other.sql and self.connection == other.connection 28 29 class SchemaBuilder(object): 30 def __init__(self): 31 self.models_already_seen = [] 32 33 def get_create_table(self, model, style=dummy()): 34 if model in self.models_already_seen: 35 return (None, None, None) 36 self.models_already_seen.append(model) 37 38 opts = model._meta 39 info = opts.connection_info 40 backend = info.backend 41 quote_name = backend.quote_name 42 data_types = info.get_creation_module().DATA_TYPES 43 table_output = [] 44 pending_references = {} 45 pending = [] # actual pending statements to execute 46 for f in opts.fields: 47 if isinstance(f, models.ForeignKey): 48 rel_field = f.rel.get_related_field() 49 data_type = self.get_rel_data_type(rel_field) 50 else: 51 rel_field = f 52 data_type = f.get_internal_type() 53 col_type = data_types[data_type] 54 if col_type is not None: 55 # Make the definition (e.g. 'foo VARCHAR(30)') for this field. 56 field_output = [style.SQL_FIELD(quote_name(f.column)), 57 style.SQL_COLTYPE(col_type % rel_field.__dict__)] 58 field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) 59 if f.unique: 60 field_output.append(style.SQL_KEYWORD('UNIQUE')) 61 if f.primary_key: 62 field_output.append(style.SQL_KEYWORD('PRIMARY KEY')) 63 if f.rel: 64 if f.rel.to in self.models_already_seen: 65 field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ 66 style.SQL_TABLE(quote_name(f.rel.to._meta.db_table)) + ' (' + \ 67 style.SQL_FIELD(quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' 68 ) 69 else: 70 # We haven't yet created the table to which this field 71 # is related, so save it for later. 72 pr = pending_references.setdefault(f.rel.to, []).append(f) 73 table_output.append(' '.join(field_output)) 74 if opts.order_with_respect_to: 75 table_output.append(style.SQL_FIELD(quote_name('_order')) + ' ' + \ 76 style.SQL_COLTYPE(data_types['IntegerField']) + ' ' + \ 77 style.SQL_KEYWORD('NULL')) 78 for field_constraints in opts.unique_together: 79 table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ 80 ", ".join([quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints])) 81 82 full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(quote_name(opts.db_table)) + ' ('] 83 for i, line in enumerate(table_output): # Combine and add commas. 84 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 85 full_statement.append(');') 86 87 create = [BoundStatement('\n'.join(full_statement), opts.connection)] 88 89 if (pending_references and 90 backend.supports_constraints): 91 for rel_class, cols in pending_references.items(): 92 for f in cols: 93 rel_opts = rel_class._meta 94 r_table = rel_opts.db_table 95 r_col = f.column 96 table = opts.db_table 97 col = opts.get_field(f.rel.field_name).column 98 sql = style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \ 99 (quote_name(table), 100 quote_name('%s_referencing_%s_%s' % (r_col, r_table, col)), 101 quote_name(r_col), quote_name(r_table), quote_name(col)) 102 pending.append(BoundStatement(sql, opts.connection)) 103 return (create, pending) 104 105 def get_create_indexes(self, model, style=dummy()): 106 return [] # FIXME 107 108 def get_initialdata(self, model, style=dummy()): 109 return [] # FIXME 110 111 def get_rel_data_type(self, f): 112 return (f.get_internal_type() in ('AutoField', 'PositiveIntegerField', 113 'PositiveSmallIntegerField')) \ 114 and 'IntegerField' \ 115 or f.get_internal_type() -
tests/modeltests/multiple_databases/__init__.py
=== tests/modeltests/multiple_databases/__init__.py ==================================================================
1 pass -
tests/modeltests/multiple_databases/models.py
=== tests/modeltests/multiple_databases/models.py ==================================================================
1 """ 2 N. Using multiple database connections 3 4 Django normally uses only a single database connection. However, support is 5 available for connecting to any number of different, named databases on a 6 per-model-class level. 7 8 Please note that this test uses hard-coded databases, and will fail 9 unless sqlite3 is install and /tmp is writeable. It also will 10 currently fail unless the two temp databases are removed by hand 11 between runs. It also side-effects the settings as set in the 12 DJANGO_SETTINGS_MODULE. All of these are undesirable, and mean that 13 this test is almost certainly going to have to move to othertests. 14 15 It would be really nice if the testrunner supported setup and teardown. 16 17 """ 18 19 # models can define which connections they will use 20 from django.db import models 21 22 class Artist(models.Model): 23 name = models.CharField(maxlength=100) 24 alive = models.BooleanField(default=True) 25 26 def __str__(self): 27 return self.name 28 29 class Meta: 30 db_connection = 'a' 31 32 class Widget(models.Model): 33 code = models.CharField(maxlength=10, unique=True) 34 weight = models.IntegerField() 35 36 def __str__(self): 37 return self.code 38 39 class Meta: 40 db_connection = 'b' 41 42 43 # but they don't have to 44 class Vehicle(models.Model): 45 make = models.CharField(maxlength=20) 46 model = models.CharField(maxlength=20) 47 year = models.IntegerField() 48 49 def __str__(self): 50 return "%d %s %s" % (self.year, self.make, self.model) 51 52 API_TESTS = """ 53 54 # Connections are established lazily, when requested by name. 55 56 >>> from django.conf import settings 57 >>> settings.DATABASES = { 58 ... 'a': { 'DATABASE_ENGINE': 'sqlite3', 59 ... 'DATABASE_NAME': '/tmp/dba.db' 60 ... }, 61 ... 'b': { 'DATABASE_ENGINE': 'sqlite3', 62 ... 'DATABASE_NAME': '/tmp/dbb.db' 63 ... }} 64 >>> from django.db import connections 65 66 # connections[database] holds a tuple of connection, DatabaseError, backend, 67 # get_introspection_module, get_creation_module, and runshell 68 69 >>> connections['a'] 70 Connection: <django.db.backends.sqlite3.base.DatabaseWrapper object at ...> (ENGINE=sqlite3 NAME=/tmp/dba.db) 71 >>> connections['b'] 72 Connection: <django.db.backends.sqlite3.base.DatabaseWrapper object at ...> (ENGINE=sqlite3 NAME=/tmp/dbb.db) 73 74 # Invalid connection names raise ImproperlyConfigured 75 76 >>> connections['bad'] 77 Traceback (most recent call last): 78 ... 79 ImproperlyConfigured: No database connection 'bad' has been configured 80 81 # For the time being, we have to install the models by hand 82 83 >>> from django.core import management 84 >>> artist_sql = ''.join(management._get_sql_model_create(Artist)[0]) 85 >>> cursor = Artist._meta.connection.cursor() 86 >>> cursor.execute(artist_sql) 87 >>> widget_sql = ''.join(management._get_sql_model_create(Widget)[0]) 88 >>> cursor = Widget._meta.connection.cursor() 89 >>> cursor.execute(widget_sql) 90 91 # Then we can play with them 92 93 >>> a = Artist(name="Paul Klee", alive=False) 94 >>> a.save() 95 >>> a._meta.connection.settings.DATABASE_NAME 96 '/tmp/dba.db' 97 >>> w = Widget(code='100x2r', weight=1000) 98 >>> w.save() 99 >>> w._meta.connection.settings.DATABASE_NAME 100 '/tmp/dbb.db' 101 >>> v = Vehicle(make='Chevy', model='Camaro', year='1966') 102 >>> v.save() 103 >>> v._meta.connection.settings.DATABASE_NAME 104 ':memory:' 105 106 # Managers use their models' connections 107 108 >>> artists = Artist.objects.all() 109 >>> list(artists) 110 [<Artist: Paul Klee>] 111 >>> artists[0]._meta.connection.settings.DATABASE_NAME 112 '/tmp/dba.db' 113 >>> widgets = Widget.objects.all() 114 >>> list(widgets) 115 [<Widget: 100x2r>] 116 >>> widgets[0]._meta.connection.settings.DATABASE_NAME 117 '/tmp/dbb.db' 118 >>> vehicles = Vehicle.objects.all() 119 >>> list(vehicles) 120 [<Vehicle: 1966 Chevy Camaro>] 121 >>> vehicles[0]._meta.connection.settings.DATABASE_NAME 122 ':memory:' 123 124 # Managed transactions may be restricted to certain databases 125 126 # But by default they cover all databases 127 128 129 """ -
tests/modeltests/manager_schema_manipulation/__init__.py
=== tests/modeltests/manager_schema_manipulation/__init__.py ==================================================================
1 pass -
tests/modeltests/manager_schema_manipulation/models.py
=== tests/modeltests/manager_schema_manipulation/models.py ==================================================================
1 """ 2 N. Schema manipulations 3 4 Django uses a model's manager to perform schema manipulations such as 5 creating or dropping the model's table. 6 7 Please note that your settings file must define DATABASES with names 8 'a' and 'b' for this test. 9 """ 10 11 from django.db import models 12 13 # default connection 14 class DA(models.Model): 15 name = models.CharField(maxlength=20) 16 17 def __str__(self): 18 return self.name 19 20 # connection a 21 class AA(models.Model): 22 name = models.CharField(maxlength=20) 23 # This creates a cycle in the dependency graph 24 c = models.ForeignKey('AC', null=True) 25 26 def __str__(self): 27 return self.name 28 29 class Meta: 30 db_connection = 'a' 31 32 class AB(models.Model): 33 name = models.CharField(maxlength=20) 34 a = models.ForeignKey(AA) 35 36 def __str__(self): 37 return self.name 38 39 class Meta: 40 db_connection = 'a' 41 42 class AC(models.Model): 43 name = models.CharField(maxlength=20) 44 b = models.ForeignKey(AB) 45 46 def __str__(self): 47 return self.name 48 49 class Meta: 50 db_connection = 'a' 51 52 # connection b 53 class BA(models.Model): 54 name = models.CharField(maxlength=20) 55 56 def __str__(self): 57 return self.name 58 59 class Meta: 60 db_connection = 'b' 61 62 class BB(models.Model): 63 name = models.CharField(maxlength=20) 64 a = models.ForeignKey(BA) 65 66 def __str__(self): 67 return self.name 68 69 class Meta: 70 db_connection = 'b' 71 72 73 74 API_TESTS = """ 75 76 # models can use the default connection or a named connection 77 78 # FIXME: DA is already installed 79 # models can be installed individually 80 81 >>> BA._default_manager.install() 82 (<class 'modeltests.manager_schema_manipulation.models.BA'>, [BoundStatement('CREATE TABLE "manager_schema_manipulation_ba" (...);')], []) 83 >>> BB._default_manager.install() 84 (<class 'modeltests.manager_schema_manipulation.models.BB'>, [BoundStatement('CREATE TABLE "manager_schema_manipulation_bb" (...);')], []) 85 >>> list(BA.objects.all()) 86 [] 87 >>> BA(name="something").save() 88 >>> BA.objects.all() 89 [<BA: something>] 90 91 # models with un-installable dependencies will return a list of 92 # pending statements; these are bound to the model's connection and should 93 # be executed after all other models have been created 94 95 >>> result = AA._default_manager.install() 96 >>> result 97 (<class 'modeltests.manager_schema_manipulation.models.AA'>, [BoundStatement('CREATE TABLE "manager_schema_manipulation_aa" (...);')], [BoundStatement('ALTER TABLE "manager_schema_manipulation_aa" ADD CONSTRAINT "c_id_referencing_manager_schema_manipulation_ac_id" FOREIGN KEY ("c_id") REFERENCES "manager_schema_manipulation_ac" ("id");')]) 98 99 100 """