'Given a table and three sets of changes (renames, deletes, alters),
recreates it with the modified schema.'

@generic.invalidate_table_constraints
def _remake_table(self, table_name, added={}, renames={}, deleted=[], altered={}, primary_key_override=None, uniques_deleted=[]):

    if self.dry_run:
        return
    temp_name = ('_south_new_' + table_name)
    definitions = {}
    cursor = self._get_connection().cursor()
    indexes = self._get_connection().introspection.get_indexes(cursor, table_name)
    standalone_indexes = self._get_standalone_indexes(table_name)
    for column_info in self._get_full_table_description(self._get_connection(), cursor, table_name):
        name = column_info['name']
        if (name in deleted):
            continue
        type = column_info['type'].replace('PRIMARY    KEY', '')
        if ((primary_key_override and (primary_key_override == name)) or ((not primary_key_override) and (name in indexes) and indexes[name]['primary_key'])):
            type += '    PRIMARY    KEY'
        elif (not column_info['null_ok']):
            type += '    NOT    NULL'
        if ((name in indexes) and indexes[name]['unique'] and (name not in uniques_deleted)):
            type += '    UNIQUE'
        if (column_info['dflt_value'] is not None):
            type += ('    DEFAULT    ' + column_info['dflt_value'])
        if (name in renames):
            name = renames[name]
        definitions[name] = type
    for (name, type) in altered.items():
        if ((primary_key_override and (primary_key_override == name)) or ((not primary_key_override) and (name in indexes) and indexes[name]['primary_key'])):
            type += '    PRIMARY    KEY'
        if ((name in indexes) and indexes[name]['unique'] and (name not in uniques_deleted)):
            type += '    UNIQUE'
        definitions[name] = type
    for (name, (type, _)) in added.items():
        if (primary_key_override and (primary_key_override == name)):
            type += '    PRIMARY    KEY'
        definitions[name] = type
    self.execute(('CREATE    TABLE    %s    (%s)' % (self.quote_name(temp_name), ',    '.join([('%s    %s' % (self.quote_name(cname), ctype)) for (cname, ctype) in definitions.items()]))))
    self._copy_data(table_name, temp_name, renames, added)
    self.delete_table(table_name)
    self.rename_table(temp_name, table_name)
    self._make_standalone_indexes(table_name, standalone_indexes, renames=renames, deleted=deleted, uniques_deleted=uniques_deleted)
    self.deferred_sql = []
