def do_rename(self, change): try: sql = SQL() sql.extend(self.ops.get_change_table_name_sql(change.left, change.right)) if change.nested: commands = [(change, sql)] commands.extend(self.do_try_update(change)) return commands except RebuildTableNeededException: return self.do_rebuild(change) return sql
def get_rebuild_table_sql(self, left, right, renames): """ Renames: right => left """ old_names = left.fields.keys() #print "Renames:", renames # used instead of column renames, additions and removals qn = self.connection.ops.quote_name kw = self.style.SQL_KEYWORD fld = self.style.SQL_FIELD tqn = lambda s: self.style.SQL_TABLE(qn(s)) fqn = lambda s: self.style.SQL_FIELD(qn(s)) fqv = lambda s: self.style.SQL_FIELD(self.quote_value(s)) sql = SQL('-- FYI: next few lines could take a while if you have a lot of data') tmp_table_name = right.name + '_1337_TMP' # unlikely to produce a namespace conflict temp = DBTable(tmp_table_name) sql.extend(self.get_change_table_name_sql(left, temp)) sql.extend(self.get_create_table_sql(right)) updated = [] for f in right.fields.values(): if f.name in renames: updated.append(fqn(renames[f.name])) # copy renamed column elif f.name in old_names: updated.append(fqn(f.name)) # copy column else: default = NotProvided if f.allow_null: default = None elif f.primary_key: default = '0' elif f.coltype.coltype in ['int', 'bool', 'tinyint']: default = '0' elif f.coltype.coltype in ['varchar', 'text']: default = '' default = get_field_default(f, default) # add column with default value set if default is None: updated.append('NULL') else: updated.append(fqv(default)) sql.append(kw('INSERT INTO ') + tqn(right.name) + kw(' SELECT ') + fld(','.join(updated)) + kw(' FROM ') + tqn(tmp_table_name) +';') sql.extend(self.get_drop_table_sql(temp)) sql.extend(self.get_create_table_indexes_sql(right)) return sql
def get_create_table_indexes_sql(self, table): sql = SQL() for index in table.indexes.values(): sql.extend(self.get_create_index_sql(table, index)) return sql