=== django/db/models/base.py
==================================================================
--- django/db/models/base.py	(/local/django)	(revision 5798)
+++ django/db/models/base.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -38,7 +38,7 @@
                 new_class._meta.parents.extend(base._meta.parents)
 
         model_module = sys.modules[new_class.__module__]
-
+        
         if getattr(new_class._meta, 'app_label', None) is None:
             # Figure out the app_label by looking one level up.
             # For 'django.contrib.sites.models', this would be 'sites'.
@@ -149,7 +149,7 @@
         dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self)
 
         non_pks = [f for f in self._meta.fields if not f.primary_key]
-        cursor = connection.cursor()
+        cursor = self._meta.connection.cursor()
 
         # First, try an UPDATE. If that doesn't update anything, do an INSERT.
         pk_val = self._get_pk_val()
@@ -362,7 +362,7 @@
         rel = rel_field.rel.to
         m2m_table = rel_field.m2m_db_table()
         this_id = self._get_pk_val()
-        cursor = connection.cursor()
+        cursor = self._meta.connection.cursor()
         cursor.execute("DELETE FROM %s WHERE %s = %%s" % \
             (backend.quote_name(m2m_table),
             backend.quote_name(rel_field.m2m_column_name())), [this_id])
@@ -380,6 +380,10 @@
 # ORDERING METHODS #########################
 
 def method_set_order(ordered_obj, self, id_list):
+    connection_info = ordered_obj.connection_info
+    connection = info.connection
+    backend = info.backend
+    
     cursor = connection.cursor()
     # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
     sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \
@@ -391,6 +395,9 @@
     transaction.commit_unless_managed()
 
 def method_get_order(ordered_obj, self):
+    connection_info = ordered_obj.connection_info
+    connection = info.connection
+    backend = info.backend
     cursor = connection.cursor()
     # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order"
     sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \
=== django/db/models/manager.py
==================================================================
--- django/db/models/manager.py	(/local/django)	(revision 5798)
+++ django/db/models/manager.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -95,6 +95,48 @@
     def values(self, *args, **kwargs):
         return self.get_query_set().values(*args, **kwargs)
 
+    #######################
+    # SCHEMA MANIPULATION #
+    #######################
+
+    def install(self, initial_data=False):
+        """Install my model's table, indexes and (if requested) initial data.
+
+        Returns a 3-tuple of the model and lists of statements executed and
+        statements pending. Pending statements are those that could
+        not yet be executed, such as foreign key constraints for
+        tables that don't exist at install time.
+        """
+        creator = self.model._meta.connection_info.get_creation_module()
+        create, pending = creator.get_create_table(self.model)
+        create += creator.get_create_indexes(self.model)
+        if initial_data:
+            create += creator.get_initialdata(self.model)
+
+        executed = []
+        for statement in create:
+            statement.execute()
+        return (self.model, create, pending)
+
+    def load_initial_data(self):
+        """Load initial data for my model into the database."""
+        pass
+
+    def drop(self):
+        """Drop my model's table."""
+        pass
+
+    # Future...
+    
+    def add_column(self, column):
+        """Add a column to my model's table"""
+        pass
+
+    def drop_column(self, column):
+        """Drop a column from my model's table"""
+        pass
+        
+
 class ManagerDescriptor(object):
     # This class ensures managers aren't accessible via model instances.
     # For example, Poll.objects works, but poll_obj.objects raises AttributeError.
=== django/db/models/options.py
==================================================================
--- django/db/models/options.py	(/local/django)	(revision 5798)
+++ django/db/models/options.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -1,4 +1,5 @@
 from django.conf import settings
+from django.db import connection_info, connections
 from django.db.models.related import RelatedObject
 from django.db.models.fields.related import ManyToManyRel
 from django.db.models.fields import AutoField, FieldDoesNotExist
@@ -11,7 +12,7 @@
 # Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces".
 get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip()
 
-DEFAULT_NAMES = ('verbose_name', 'db_table', 'ordering',
+DEFAULT_NAMES = ('verbose_name', 'db_connection', 'db_table', 'ordering',
                  'unique_together', 'permissions', 'get_latest_by',
                  'order_with_respect_to', 'app_label')
 
@@ -20,6 +21,7 @@
         self.fields, self.many_to_many = [], []
         self.module_name, self.verbose_name = None, None
         self.verbose_name_plural = None
+        self.db_connection = None
         self.db_table = ''
         self.ordering = []
         self.unique_together =  []
@@ -56,6 +58,7 @@
                 raise TypeError, "'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())
         else:
             self.verbose_name_plural = self.verbose_name + 's'
+        # 
         del self.meta
 
     def _prepare(self, model):
@@ -88,6 +91,17 @@
     def __repr__(self):
         return '<Options for %s>' % self.object_name
 
+    def get_connection_info(self):
+        if self.db_connection:
+            return connections[self.db_connection]
+        return connection_info
+    connection_info = property(get_connection_info)
+            
+    def get_connection(self):
+        """Get the database connection for this object's model"""
+        return self.get_connection_info().connection
+    connection = property(get_connection)
+    
     def get_field(self, name, many_to_many=True):
         "Returns the requested field by name. Raises FieldDoesNotExist on error."
         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	(/local/django)	(revision 5798)
+++ django/db/models/loading.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -8,7 +8,9 @@
 _app_list = None # Cache of installed apps.
 _app_models = {} # Dictionary of models against app label
                  # Each value is a dictionary of model name: model class
-
+_app_model_order = {} # Dictionary of models against app label
+                      # Each value is a list of model names, in the order in
+                      # which the models were created
 def get_apps():
     "Returns a list of all installed modules that contain models."
     global _app_list
@@ -35,14 +37,21 @@
             return __import__(app_name, '', '', ['models']).models
     raise ImproperlyConfigured, "App with label %s could not be found" % app_label
 
-def get_models(app_mod=None):
+def get_models(app_mod=None, creation_order=False):
     """
     Given a module containing models, returns a list of the models. Otherwise
-    returns a list of all installed models.
+    returns a list of all installed models. In either case, if creation_order
+    is true, return the models sorted into the same order in which they
+    were created.
     """
     app_list = get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish.
     if app_mod:
-        return _app_models.get(app_mod.__name__.split('.')[-2], {}).values()
+        app_label = app_mod.__name__.split('.')[-2]
+        app_models = _app_models.get(app_label, {})
+        if creation_order:
+            return [ app_models[name]
+                     for name in _app_model_order.get(app_label, []) ]
+        return app_models.values()
     else:
         model_list = []
         for app_mod in app_list:
@@ -75,3 +84,5 @@
         model_name = model._meta.object_name.lower()
         model_dict = _app_models.setdefault(app_label, {})
         model_dict[model_name] = model
+        model_list = _app_model_order.setdefault(app_label, [])
+        model_list.append(model_name)
=== django/db/models/query.py
==================================================================
--- django/db/models/query.py	(/local/django)	(revision 5798)
+++ django/db/models/query.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -1,4 +1,4 @@
-from django.db import backend, connection, transaction
+from django.db import backend, connection, connections, transaction
 from django.db.models.fields import DateField, FieldDoesNotExist
 from django.db.models import signals
 from django.dispatch import dispatcher
@@ -158,7 +158,7 @@
         # undefined, so we convert it to a list of tuples.
         extra_select = self._select.items()
 
-        cursor = connection.cursor()
+        cursor = self.model._meta.connection.cursor()
         select, sql, params = self._get_sql_clause()
         cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
         fill_cache = self._select_related
@@ -178,6 +178,11 @@
 
     def count(self):
         "Performs a SELECT COUNT() and returns the number of records as an integer."
+
+        info = self.model._meta.connection_info
+        backend = info.backend
+        connection = info.connection
+        
         counter = self._clone()
         counter._order_by = ()
         counter._offset = None
@@ -505,6 +510,9 @@
             columns = [f.column for f in self.model._meta.fields]
             field_names = [f.attname for f in self.model._meta.fields]
 
+        info = self.model._meta.connection_info
+        backend = info.backend
+        connection = info.connection
         cursor = connection.cursor()
         select, sql, params = self._get_sql_clause()
         select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns]
@@ -524,6 +532,11 @@
 class DateQuerySet(QuerySet):
     def iterator(self):
         from django.db.backends.util import typecast_timestamp
+
+        info = self.model._meta.connection_info
+        backend = info.backend
+        connection = info.connection
+        
         self._order_by = () # Clear this because it'll mess things up otherwise.
         if self._field.null:
             self._where.append('%s.%s IS NOT NULL' % \
@@ -616,7 +629,9 @@
         where2 = ['(NOT (%s))' % " AND ".join(where)]
         return tables, joins, where2, params
 
-def get_where_clause(lookup_type, table_prefix, field_name, value):
+def get_where_clause(opts, lookup_type, table_prefix, field_name, value):
+    backend = opts.connection_info.backend
+    
     if table_prefix.endswith('.'):
         table_prefix = backend.quote_name(table_prefix[:-1])+'.'
     field_name = backend.quote_name(field_name)
@@ -745,6 +760,10 @@
     intermediate_table = None
     join_required = False
 
+    info = current_opts.connection_info
+    backend = info.backend
+    connection = info.connection
+
     name = path.pop(0)
     # Has the primary key been requested? If so, expand it out
     # to be the name of the current class' primary key
@@ -872,7 +891,7 @@
         else:
             column = field.column
 
-        where.append(get_where_clause(clause, current_table + '.', column, value))
+        where.append(get_where_clause(current_opts, clause, current_table + '.', column, value))
         params.extend(field.get_db_prep_lookup(clause, value))
 
     return tables, joins, where, params
@@ -882,9 +901,14 @@
     ordered_classes = seen_objs.keys()
     ordered_classes.reverse()
 
-    cursor = connection.cursor()
 
     for cls in ordered_classes:
+
+        info = cls._meta.connection_info
+        backend = info.backend
+        connection = info.connection
+        cursor = connection.cursor()
+        
         seen_objs[cls] = seen_objs[cls].items()
         seen_objs[cls].sort()
 
@@ -919,6 +943,12 @@
 
     # Now delete the actual data
     for cls in ordered_classes:
+
+        info = cls._meta.connection_info
+        backend = info.backend
+        connection = info.connection
+        cursor = connection.cursor()
+
         seen_objs[cls].reverse()
         pk_list = [pk for pk,instance in seen_objs[cls]]
         for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
=== django/db/__init__.py
==================================================================
--- django/db/__init__.py	(/local/django)	(revision 5798)
+++ django/db/__init__.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -1,5 +1,6 @@
-from django.conf import settings
+from django.conf import settings, UserSettingsHolder
 from django.core import signals
+from django.core.exceptions import ImproperlyConfigured
 from django.dispatch import dispatcher
 
 __all__ = ('backend', 'connection', 'DatabaseError')
@@ -7,36 +8,114 @@
 if not settings.DATABASE_ENGINE:
     settings.DATABASE_ENGINE = 'dummy'
 
-try:
-    backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, '', '', [''])
-except ImportError, e:
-    # The database backend wasn't found. Display a helpful error message
-    # listing all possible database backends.
-    from django.core.exceptions import ImproperlyConfigured
-    import os
-    backend_dir = os.path.join(__path__[0], 'backends')
-    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')]
-    available_backends.sort()
-    if settings.DATABASE_ENGINE not in available_backends:
-        raise ImproperlyConfigured, "%r isn't an available database backend. vailable options are: %s" % \
-            (settings.DATABASE_ENGINE, ", ".join(map(repr, available_backends)))
-    else:
-        raise # If there's some other error, this must be an error in Django itself.
+class ConnectionInfo(object):
+    """Encapsulates all information about a db connection:
+     - connection
+     - DatabaseError
+     - backend
+     - get_introspection_module
+     - get_creation_module
+     - runshell
+    """
+    def __init__(self, connection, DatabaseError, backend, 
+                 get_introspection_module, get_creation_module, runshell):
+        self.connection = connection
+        self.DatabaseError = DatabaseError
+        self.backend = backend
+        self.get_introspection_module = get_introspection_module
+        self.get_creation_module = get_creation_module
+        self.runshell = runshell
 
-get_introspection_module = lambda: __import__('django.db.backends.%s.introspection' % settings.DATABASE_ENGINE, '', '', [''])
-get_creation_module = lambda: __import__('django.db.backends.%s.creation' % settings.DATABASE_ENGINE, '', '', [''])
-runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, '', '', ['']).runshell()
+    def __repr__(self):
+        return "Connection: %r (ENGINE=%s NAME=%s)" \
+               % (self.connection,
+                  self.connection.settings.DATABASE_ENGINE,
+                  self.connection.settings.DATABASE_NAME)
 
-connection = backend.DatabaseWrapper()
-DatabaseError = backend.DatabaseError
+def connect(settings=settings):
+    """Connect to the database specified in the given settings.
+    """
+    try:
+        backend = __import__('django.db.backends.%s.base' % settings.DATABASE_ENGINE, '', '', [''])
+    except ImportError, e:
+        # The database backend wasn't found. Display a helpful error message
+        # listing all possible database backends.
+        import os
+        backend_dir = os.path.join(__path__[0], 'backends')
+        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')]
+        available_backends.sort()
+        if settings.DATABASE_ENGINE not in available_backends:
+            raise ImproperlyConfigured, "%r isn't an available database backend. vailable options are: %s" % \
+                (settings.DATABASE_ENGINE, ", ".join(map(repr, available_backends)))
+        else:
+            raise # If there's some other error, this must be an error in Django itself.
 
-# Register an event that closes the database connection
-# when a Django request is finished.
-dispatcher.connect(connection.close, signal=signals.request_finished)
 
+    get_introspection_module = lambda: __import__('django.db.backends.%s.introspection' % settings.DATABASE_ENGINE, '', '', [''])
+    get_creation_module = lambda: __import__('django.db.backends.%s.creation' % settings.DATABASE_ENGINE, '', '', [''])
+    runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, '', '', ['']).runshell()
+
+    connection = backend.DatabaseWrapper(settings)
+    DatabaseError = backend.DatabaseError
+
+    return ConnectionInfo(connection, DatabaseError, backend, 
+                          get_introspection_module, get_creation_module,
+                          runshell)
+
+connection_info = connect(settings)
+
+# backwards compatibility
+(connection, DatabaseError, backend, get_introspection_module, 
+ get_creation_module, runshell) = (connection_info.connection,
+                                   connection_info.DatabaseError,
+                                   connection_info.backend,
+                                   connection_info.get_introspection_module, 
+                                   connection_info.get_creation_module,
+                                   connection_info.runshell)
+
+
+class LazyConnectionManager(object):
+    """Manages named connections lazily, instantiating them as
+    they are requested.
+    """
+
+    def __init__(self):
+        self._connections = {}
+
+    def __getitem__(self, k):
+        try:
+            return self._connections[k]
+        except KeyError:
+            try:
+                self.connect(k)
+                return self._connections[k]
+            except KeyError:
+                raise ImproperlyConfigured, \
+                      "No database connection '%s' has been configured" % k
+            
+    def connect(self, name):
+        from django.conf import settings
+        try:
+            database = settings.DATABASES[name]
+            try:
+                database.DATABASE_ENGINE
+            except AttributeError:
+                # assume its a dict and convert to settings instance
+                holder = UserSettingsHolder(settings)
+                for k, v in database.items():
+                    setattr(holder, k, v)
+                    database = holder
+                settings.DATABASES[name] = database
+            self._connections[name] = connect(database)
+        except AttributeError:
+            # no named connections to set up
+            pass
+
+connections = LazyConnectionManager()
+
 # Register an event that resets connection.queries
 # when a Django request is started.
-def reset_queries():
+def reset_queries(connection=connection):
     connection.queries = []
 dispatcher.connect(reset_queries, signal=signals.request_started)
 
@@ -46,3 +125,8 @@
     from django.db import transaction
     transaction.rollback_unless_managed()
 dispatcher.connect(_rollback_on_exception, signal=signals.got_request_exception)
+
+# Register an event that closes the database connection
+# when a Django request is finished.
+dispatcher.connect(connection.close, signal=signals.request_finished)
+
=== django/db/backends/postgresql/base.py
==================================================================
--- django/db/backends/postgresql/base.py	(/local/django)	(revision 5798)
+++ django/db/backends/postgresql/base.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -21,12 +21,13 @@
     from django.utils._threading_local import local
 
 class DatabaseWrapper(local):
-    def __init__(self):
+    def __init__(self, settings):
+        self.settings = settings
         self.connection = None
         self.queries = []
 
     def cursor(self):
-        from django.conf import settings
+        settings = self.settings
         if self.connection is None:
             if settings.DATABASE_NAME == '':
                 from django.core.exceptions import ImproperlyConfigured
=== django/db/backends/postgresql/creation.py
==================================================================
--- django/db/backends/postgresql/creation.py	(/local/django)	(revision 5798)
+++ django/db/backends/postgresql/creation.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -1,3 +1,5 @@
+from django.db.backends.ansi.creation import SchemaBuilder
+
 # This dictionary maps Field objects to their associated PostgreSQL column
 # types, as strings. Column-type strings can contain format strings; they'll
 # be interpolated against the values of Field.__dict__ before being output.
@@ -28,3 +30,8 @@
     'URLField':          'varchar(200)',
     'USStateField':      'varchar(2)',
 }
+
+_builder = SchemaBuilder()
+get_create_table = _builder.get_create_table
+get_create_indexes = _builder.get_create_indexes
+get_initialdata = _builder.get_initialdata
=== django/db/backends/sqlite3/base.py
==================================================================
--- django/db/backends/sqlite3/base.py	(/local/django)	(revision 5798)
+++ django/db/backends/sqlite3/base.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -34,12 +34,13 @@
     from django.utils._threading_local import local
 
 class DatabaseWrapper(local):
-    def __init__(self):
+    def __init__(self, settings):
+        self.settings = settings
         self.connection = None
         self.queries = []
 
     def cursor(self):
-        from django.conf import settings
+        settings = self.settings
         if self.connection is None:
             self.connection = Database.connect(settings.DATABASE_NAME,
                 detect_types=Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES)
=== django/db/backends/sqlite3/creation.py
==================================================================
--- django/db/backends/sqlite3/creation.py	(/local/django)	(revision 5798)
+++ django/db/backends/sqlite3/creation.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -1,3 +1,5 @@
+from django.db.backends.ansi.creation import SchemaBuilder
+
 # SQLite doesn't actually support most of these types, but it "does the right
 # thing" given more verbose field definitions, so leave them as is so that
 # schema inspection is more useful.
@@ -27,3 +29,8 @@
     'URLField':                     'varchar(200)',
     'USStateField':                 'varchar(2)',
 }
+
+_builder = SchemaBuilder()
+get_create_table = _builder.get_create_table
+get_create_indexes = _builder.get_create_indexes
+get_initialdata = _builder.get_initialdata
=== django/db/backends/ansi/__init__.py
==================================================================
--- django/db/backends/ansi/__init__.py	(/local/django)	(revision 5798)
+++ django/db/backends/ansi/__init__.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -0,0 +1 @@
+pass
=== django/db/backends/ansi/creation.py
==================================================================
--- django/db/backends/ansi/creation.py	(/local/django)	(revision 5798)
+++ django/db/backends/ansi/creation.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -0,0 +1,115 @@
+"""ANSISQL schema manipulation functions and classes
+"""
+from django.db import models
+
+# FIXME correct handling of styles,
+# allow style object to be passed in
+class dummy:
+    def __getattr__(self, attr):
+        return lambda x: x
+
+class BoundStatement(object):    
+    def __init__(self, sql, connection):
+        self.sql = sql
+        self.connection = connection
+
+    def execute(self):
+        cursor = self.connection.cursor()
+        cursor.execute(self.sql)
+
+    def __repr__(self):
+        return "BoundStatement(%r)" % self.sql
+
+    def __str__(self):
+        return self.sql
+
+    def __eq__(self, other):
+        return self.sql == other.sql and self.connection == other.connection
+
+class SchemaBuilder(object):
+    def __init__(self):
+        self.models_already_seen = []
+        
+    def get_create_table(self, model, style=dummy()):
+        if model in self.models_already_seen:
+            return (None, None, None)
+        self.models_already_seen.append(model)
+        
+        opts = model._meta
+        info = opts.connection_info
+        backend = info.backend
+        quote_name = backend.quote_name
+        data_types = info.get_creation_module().DATA_TYPES
+        table_output = []
+        pending_references = {} 
+        pending = [] # actual pending statements to execute
+        for f in opts.fields:
+            if isinstance(f, models.ForeignKey):
+                rel_field = f.rel.get_related_field()
+                data_type = self.get_rel_data_type(rel_field)
+            else:
+                rel_field = f
+                data_type = f.get_internal_type()
+            col_type = data_types[data_type]
+            if col_type is not None:
+                # Make the definition (e.g. 'foo VARCHAR(30)') for this field.
+                field_output = [style.SQL_FIELD(quote_name(f.column)),
+                    style.SQL_COLTYPE(col_type % rel_field.__dict__)]
+                field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')))
+                if f.unique:
+                    field_output.append(style.SQL_KEYWORD('UNIQUE'))
+                if f.primary_key:
+                    field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
+                if f.rel:
+                    if f.rel.to in self.models_already_seen:
+                        field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \
+                            style.SQL_TABLE(quote_name(f.rel.to._meta.db_table)) + ' (' + \
+                            style.SQL_FIELD(quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')'
+                        )
+                    else:
+                        # We haven't yet created the table to which this field
+                        # is related, so save it for later.
+                        pr = pending_references.setdefault(f.rel.to, []).append(f)
+                table_output.append(' '.join(field_output))
+        if opts.order_with_respect_to:
+            table_output.append(style.SQL_FIELD(quote_name('_order')) + ' ' + \
+                style.SQL_COLTYPE(data_types['IntegerField']) + ' ' + \
+                style.SQL_KEYWORD('NULL'))
+        for field_constraints in opts.unique_together:
+            table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \
+                ", ".join([quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))
+
+        full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(quote_name(opts.db_table)) + ' (']
+        for i, line in enumerate(table_output): # Combine and add commas.
+            full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or ''))
+        full_statement.append(');')
+
+        create = [BoundStatement('\n'.join(full_statement), opts.connection)]
+
+        if (pending_references and
+            backend.supports_constraints):
+            for rel_class, cols in pending_references.items():
+                for f in cols:
+                    rel_opts = rel_class._meta
+                    r_table = rel_opts.db_table
+                    r_col = f.column
+                    table = opts.db_table
+                    col = opts.get_field(f.rel.field_name).column
+                    sql = style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \
+                        (quote_name(table),
+                        quote_name('%s_referencing_%s_%s' % (r_col, r_table, col)),
+                        quote_name(r_col), quote_name(r_table), quote_name(col))
+                    pending.append(BoundStatement(sql, opts.connection))
+        return (create, pending)    
+
+    def get_create_indexes(self, model, style=dummy()):
+        return [] # FIXME
+
+    def get_initialdata(self, model, style=dummy()):
+        return [] # FIXME
+
+    def get_rel_data_type(self, f):
+        return (f.get_internal_type() in ('AutoField', 'PositiveIntegerField',
+                                          'PositiveSmallIntegerField')) \
+                                          and 'IntegerField' \
+                                          or f.get_internal_type()
=== tests/modeltests/multiple_databases/__init__.py
==================================================================
--- tests/modeltests/multiple_databases/__init__.py	(/local/django)	(revision 5798)
+++ tests/modeltests/multiple_databases/__init__.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -0,0 +1 @@
+pass
=== tests/modeltests/multiple_databases/models.py
==================================================================
--- tests/modeltests/multiple_databases/models.py	(/local/django)	(revision 5798)
+++ tests/modeltests/multiple_databases/models.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -0,0 +1,129 @@
+"""
+N. Using multiple database connections
+
+Django normally uses only a single database connection. However, support is
+available for connecting to any number of different, named databases on a
+per-model-class level.
+
+Please note that this test uses hard-coded databases, and will fail
+unless sqlite3 is install and /tmp is writeable. It also will
+currently fail unless the two temp databases are removed by hand
+between runs. It also side-effects the settings as set in the
+DJANGO_SETTINGS_MODULE. All of these are undesirable, and mean that
+this test is almost certainly going to have to move to othertests.
+
+It would be really nice if the testrunner supported setup and teardown.
+
+"""
+
+# models can define which connections they will use
+from django.db import models
+
+class Artist(models.Model):
+    name = models.CharField(maxlength=100)
+    alive = models.BooleanField(default=True)
+
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_connection = 'a'
+        
+class Widget(models.Model):
+    code = models.CharField(maxlength=10, unique=True)
+    weight = models.IntegerField()
+
+    def __str__(self):
+        return self.code
+    
+    class Meta:
+        db_connection = 'b'
+
+
+# but they don't have to
+class Vehicle(models.Model):
+    make = models.CharField(maxlength=20)
+    model = models.CharField(maxlength=20)
+    year = models.IntegerField()
+
+    def __str__(self):
+        return "%d %s %s" % (self.year, self.make, self.model)
+
+API_TESTS = """
+
+# Connections are established lazily, when requested by name.
+
+>>> from django.conf import settings
+>>> settings.DATABASES = { 
+...     'a': { 'DATABASE_ENGINE': 'sqlite3',
+...            'DATABASE_NAME': '/tmp/dba.db'
+...     },
+...     'b': { 'DATABASE_ENGINE': 'sqlite3',
+...            'DATABASE_NAME': '/tmp/dbb.db'
+...     }}
+>>> from django.db import connections
+
+# connections[database] holds a tuple of connection, DatabaseError, backend, 
+# get_introspection_module, get_creation_module, and runshell
+
+>>> connections['a']
+Connection: <django.db.backends.sqlite3.base.DatabaseWrapper object at ...> (ENGINE=sqlite3 NAME=/tmp/dba.db)
+>>> connections['b']
+Connection: <django.db.backends.sqlite3.base.DatabaseWrapper object at ...> (ENGINE=sqlite3 NAME=/tmp/dbb.db)
+
+# Invalid connection names raise ImproperlyConfigured
+
+>>> connections['bad']
+Traceback (most recent call last):
+    ...
+ImproperlyConfigured: No database connection 'bad' has been configured
+
+# For the time being, we have to install the models by hand
+
+>>> from django.core import management
+>>> artist_sql = ''.join(management._get_sql_model_create(Artist)[0])
+>>> cursor = Artist._meta.connection.cursor()
+>>> cursor.execute(artist_sql)
+>>> widget_sql = ''.join(management._get_sql_model_create(Widget)[0])
+>>> cursor = Widget._meta.connection.cursor()
+>>> cursor.execute(widget_sql)
+
+# Then we can play with them
+
+>>> a = Artist(name="Paul Klee", alive=False)
+>>> a.save()
+>>> a._meta.connection.settings.DATABASE_NAME
+'/tmp/dba.db'
+>>> w = Widget(code='100x2r', weight=1000)
+>>> w.save()
+>>> w._meta.connection.settings.DATABASE_NAME
+'/tmp/dbb.db'
+>>> v = Vehicle(make='Chevy', model='Camaro', year='1966')
+>>> v.save()
+>>> v._meta.connection.settings.DATABASE_NAME
+':memory:'
+
+# Managers use their models' connections
+
+>>> artists = Artist.objects.all()
+>>> list(artists)
+[<Artist: Paul Klee>]
+>>> artists[0]._meta.connection.settings.DATABASE_NAME
+'/tmp/dba.db'
+>>> widgets = Widget.objects.all()
+>>> list(widgets)
+[<Widget: 100x2r>]
+>>> widgets[0]._meta.connection.settings.DATABASE_NAME
+'/tmp/dbb.db'
+>>> vehicles = Vehicle.objects.all()
+>>> list(vehicles)
+[<Vehicle: 1966 Chevy Camaro>]
+>>> vehicles[0]._meta.connection.settings.DATABASE_NAME
+':memory:'
+
+# Managed transactions may be restricted to certain databases
+
+# But by default they cover all databases
+
+
+"""
=== tests/modeltests/manager_schema_manipulation/__init__.py
==================================================================
--- tests/modeltests/manager_schema_manipulation/__init__.py	(/local/django)	(revision 5798)
+++ tests/modeltests/manager_schema_manipulation/__init__.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -0,0 +1 @@
+pass
=== tests/modeltests/manager_schema_manipulation/models.py
==================================================================
--- tests/modeltests/manager_schema_manipulation/models.py	(/local/django)	(revision 5798)
+++ tests/modeltests/manager_schema_manipulation/models.py	(/local/houdini/vendor/django)	(revision 5798)
@@ -0,0 +1,100 @@
+"""
+N. Schema manipulations
+
+Django uses a model's manager to perform schema manipulations such as
+creating or dropping the model's table.
+
+Please note that your settings file must define DATABASES with names
+'a' and 'b' for this test.
+"""
+
+from django.db import models
+
+# default connection
+class DA(models.Model):
+    name = models.CharField(maxlength=20)
+
+    def __str__(self):
+        return self.name
+    
+# connection a
+class AA(models.Model):
+    name = models.CharField(maxlength=20)
+    # This creates a cycle in the dependency graph
+    c = models.ForeignKey('AC', null=True)
+    
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_connection = 'a'
+
+class AB(models.Model):
+    name = models.CharField(maxlength=20)
+    a = models.ForeignKey(AA)
+
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_connection = 'a'
+
+class AC(models.Model):
+    name = models.CharField(maxlength=20)
+    b = models.ForeignKey(AB)
+
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_connection = 'a'
+
+# connection b
+class BA(models.Model):
+    name = models.CharField(maxlength=20)
+
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_connection = 'b'
+
+class BB(models.Model):
+    name = models.CharField(maxlength=20)
+    a = models.ForeignKey(BA)
+    
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_connection = 'b'
+
+
+
+API_TESTS = """
+
+# models can use the default connection or a named connection
+
+# FIXME: DA is already installed
+# models can be installed individually
+
+>>> BA._default_manager.install()
+(<class 'modeltests.manager_schema_manipulation.models.BA'>, [BoundStatement('CREATE TABLE "manager_schema_manipulation_ba" (...);')], [])
+>>> BB._default_manager.install()
+(<class 'modeltests.manager_schema_manipulation.models.BB'>, [BoundStatement('CREATE TABLE "manager_schema_manipulation_bb" (...);')], [])
+>>> list(BA.objects.all())
+[]
+>>> BA(name="something").save()
+>>> BA.objects.all()
+[<BA: something>]
+
+# models with un-installable dependencies will return a list of
+# pending statements; these are bound to the model's connection and should
+# be executed after all other models have been created
+
+>>> result = AA._default_manager.install()
+>>> result
+(<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");')])
+
+
+"""
  

