def add_index(self, table, columns, unique=False): compiler = self.database.compiler() statement = 'CREATE UNIQUE INDEX' if unique else 'CREATE INDEX' return Clause(SQL(statement), Entity(compiler.index_name(table, columns)), SQL('ON'), Entity(table), EnclosedClause(*[Entity(column) for column in columns]))
def add_index(self, table, columns, unique=False): ctx = self.make_context() index_name = make_index_name(table, columns) return (ctx.literal( 'CREATE UNIQUE INDEX ' if unique else 'CREATE INDEX ').sql( Entity(index_name)).literal(' ON ').sql(Entity(table)).sql( EnclosedNodeList([Entity(column) for column in columns])))
def drop_index(self, table, index_name): return (self .make_context() .literal('DROP INDEX ') .sql(Entity(index_name)) .literal(' ON ') .sql(Entity(table)))
def _alter_column(self, table, column): return [ SQL('ALTER TABLE'), Entity(table), SQL('ALTER COLUMN'), Entity(column) ]
def rename_table(self, old_name, new_name): return (self .make_context() .literal('RENAME TABLE ') .sql(Entity(old_name)) .literal(' TO ') .sql(Entity(new_name)))
def rename_column(self, table, old_name, new_name): return (self ._alter_table(self.make_context(), table) .literal(' RENAME COLUMN ') .sql(Entity(old_name)) .literal(' TO ') .sql(Entity(new_name)))
def rename_column(self, table, old_name, new_name): fk_objects = dict( (fk.column, fk) for fk in self.database.get_foreign_keys(table)) is_foreign_key = old_name in fk_objects column = self._get_column_definition(table, old_name) rename_clause = Clause( SQL('ALTER TABLE'), Entity(table), SQL('CHANGE'), Entity(old_name), column.sql(column_name=new_name)) if is_foreign_key: fk_metadata = fk_objects[old_name] return [ self.drop_foreign_key_constraint(table, old_name), rename_clause, self.add_foreign_key_constraint( table, new_name, fk_metadata.dest_table, fk_metadata.dest_column), ] else: return rename_clause
def drop_foreign_key_constraint(self, table, column_name): fk_constraint = self.get_foreign_key_constraint(table, column_name) return (self .make_context() .literal('ALTER TABLE ') .sql(Entity(table)) .literal(' DROP FOREIGN KEY ') .sql(Entity(fk_constraint)))
def rename_column(self, table, old_name, new_name): return Clause( SQL('ALTER TABLE'), Entity(table), SQL('RENAME COLUMN'), Entity(old_name), SQL('TO'), Entity(new_name))
def add_inline_fk_sql(self, ctx, field): ctx = (ctx.literal(' REFERENCES ').sql( Entity(field.rel_model._meta.table_name)).literal(' ').sql( EnclosedNodeList((Entity(field.rel_field.column_name), )))) if field.on_delete is not None: ctx = ctx.literal(' ON DELETE %s' % field.on_delete) if field.on_update is not None: ctx = ctx.literal(' ON UPDATE %s' % field.on_update) return ctx
def drop_column(self, table, column_name, cascade=True): nodes = [ SQL('ALTER TABLE'), Entity(table), SQL('DROP COLUMN'), Entity(column_name) ] if cascade: nodes.append(SQL('CASCADE')) return Clause(*nodes)
def apply_default(self, table, column_name, field): default = field.default if callable(default): default = default() return Clause( SQL('UPDATE'), Entity(table), SQL('SET'), Expression(Entity(column_name), OP.EQ, Param(field.db_value(default)), flat=True))
def apply_default(self, table, column_name, field): default = field.default if callable(default): default = default() return (self.make_context().literal('UPDATE ').sql( Entity(table)).literal(' SET ').sql( Expression(Entity(column_name), OP.EQ, field.db_value(default), flat=True)))
def add_foreign_key_constraint(self, table, column_name, rel, rel_column): # TODO: refactor, this duplicates QueryCompiler._create_foreign_key constraint = 'fk_%s_%s_refs_%s' % (table, column_name, rel) return Clause( SQL('ALTER TABLE'), Entity(table), SQL('ADD CONSTRAINT'), Entity(constraint), SQL('FOREIGN KEY'), EnclosedClause(Entity(column_name)), SQL('REFERENCES'), Entity(rel), EnclosedClause(Entity(rel_column)))
def _add_restrict_foreign_key_constraint( self, table, column_name, rel, rel_column): constraint = 'fk_%s_%s_refs_%s' % (table, column_name, rel) return [ SQL('ALTER TABLE'), Entity(table), SQL('ADD CONSTRAINT'), Entity(constraint), SQL('FOREIGN KEY'), EnclosedClause(Entity(column_name)), SQL('REFERENCES'), Entity(rel), EnclosedClause(Entity(rel_column))]
def _migrate_copy_column(table: Type[Model], source: str, dest: str) -> bool: table_name = table.__name__.lower() migrator = db_config.get_migrator_instance() with db_config.database.transaction(): (db_config.database.execute_sql( migrator.make_context().literal('UPDATE ').sql( Entity(table_name)).literal(' SET ').sql( Expression( Entity(dest), OP.EQ, SQL(' solution_id'), flat=True, ), ).query()[0], )) return True
def alter_column_type(self, table, column, field, cast=None): if cast is not None: raise ValueError('alter_column_type() does not support cast with ' 'MySQL.') ctx = self.make_context() return (self._alter_table(ctx, table).literal(' MODIFY ').sql( Entity(column)).literal(' ').sql(field.ddl(ctx)))
def rename_column(self, table, old_name, new_name): fk_objects = dict( (fk.column, fk) for fk in self.database.get_foreign_keys(table)) is_foreign_key = old_name in fk_objects column = self._get_column_definition(table, old_name) rename_ctx = (self ._alter_table(self.make_context(), table) .literal(' CHANGE ') .sql(Entity(old_name)) .literal(' ') .sql(column.sql(column_name=new_name))) if is_foreign_key: fk_metadata = fk_objects[old_name] return [ self.drop_foreign_key_constraint(table, old_name), rename_ctx, self.add_foreign_key_constraint( table, new_name, fk_metadata.dest_table, fk_metadata.dest_column), ] else: return rename_ctx
def add_not_null(self, table, column): column = self._get_column_definition(table, column) return Clause( SQL('ALTER TABLE'), Entity(table), SQL('MODIFY'), column.sql(is_null=False))
def change_column_type(self, table, new_field): # ALTER TABLE <table_name> MODIFY <col_name> VARCHAR(65353); ctx = self.make_context() field_ddl = new_field.ddl(ctx) change_ctx = (self.make_context().literal('ALTER TABLE ').sql( Entity(table)).literal(' MODIFY ').sql(field_ddl)) return change_ctx
def add_foreign_key_constraint(self, table, column_name, rel, rel_column): # TODO: refactor, this duplicates QueryCompiler._create_foreign_key constraint = 'fk_%s_%s_refs_%s' % (table, column_name, rel) return (self .make_context() .literal('ALTER TABLE ') .sql(Entity(table)) .literal(' ADD CONSTRAINT ') .sql(Entity(constraint)) .literal(' FOREIGN KEY ') .sql(EnclosedNodeList((Entity(column_name),))) .literal(' REFERENCES ') .sql(Entity(rel)) .literal(' (') .sql(Entity(rel_column)) .literal(')'))
def add_constraint(self, table, name, constraint): return (self ._alter_table(self.make_context(), table) .literal(' ADD CONSTRAINT ') .sql(Entity(name)) .literal(' ') .sql(constraint))
def alter_add_column(self, table, column_name, field): # Make field null at first. field_null, field.null = field.null, True field.name = field.db_column = column_name field_clause = self.database.compiler().field_definition(field) field.null = field_null return Clause(SQL('ALTER TABLE'), Entity(table), SQL('ADD COLUMN'), field_clause)
def drop_not_null(self, table, column): column = self._get_column_definition(table, column) if column.is_pk: raise ValueError('Primary keys can not be null') return Clause( SQL('ALTER TABLE'), Entity(table), SQL('MODIFY'), column.sql(is_null=True))
def drop_column(self, table, column_name, cascade=True): nodes = [ SQL('ALTER TABLE'), Entity(table), SQL('DROP COLUMN'), Entity(column_name)] if cascade: nodes.append(SQL('CASCADE')) drop_column_node = Clause(*nodes) fk_columns = [ foreign_key.column for foreign_key in self.database.get_foreign_keys(table)] if column_name in fk_columns and self.explicit_delete_foreign_key: return [ self.drop_foreign_key_constraint(table, column_name), drop_column_node] else: return drop_column_node
def alter_add_column(self, table, column_name, field): # Make field null at first. field_null, field.null = field.null, True field.name = field.db_column = column_name field_clause = self.database.compiler().field_definition(field) field.null = field_null parts = [ SQL('ALTER TABLE'), Entity(table), SQL('ADD COLUMN'), field_clause ] if isinstance(field, ForeignKeyField): parts.extend([ SQL('REFERENCES'), Entity(field.rel_model._meta.db_table), EnclosedClause(Entity(field.to_field.db_column)) ]) return Clause(*parts)
def drop_not_null(self, table, column): column = self._get_column_definition(table, column) if column.is_pk: raise ValueError('Primary keys can not be null') return (self .make_context() .literal('ALTER TABLE ') .sql(Entity(table)) .literal(' MODIFY ') .sql(column.sql(is_null=True)))
def add_foreign_key_constraint(self, table, column_name, rel, rel_column, on_delete=None, on_update=None): constraint = 'fk_%s_%s_refs_%s' % (table, column_name, rel) ctx = (self.make_context().literal('ALTER TABLE ').sql( Entity(table)).literal(' ADD CONSTRAINT ').sql( Entity(constraint)).literal(' FOREIGN KEY ').sql( EnclosedNodeList( (Entity(column_name), ))).literal(' REFERENCES ').sql( Entity(rel)).literal(' (').sql( Entity(rel_column)).literal(')')) if on_delete is not None: ctx = ctx.literal(' ON DELETE %s' % on_delete) if on_update is not None: ctx = ctx.literal(' ON UPDATE %s' % on_update) return ctx
def _fts_cmd_sql(cls, cmd, **extra_params): tbl = cls._meta.entity columns = [tbl] values = [cmd] for key, value in extra_params.items(): columns.append(Entity(key)) values.append(value) return NodeList( (SQL('INSERT INTO'), cls._meta.entity, EnclosedNodeList(columns), SQL('VALUES'), EnclosedNodeList(values)))
def _fts_cmd(cls, cmd, **extra_params): tbl = cls._meta.entity columns = [tbl] values = [cmd] for key, value in extra_params.items(): columns.append(Entity(key)) values.append(value) inner_clause = EnclosedClause(tbl) clause = Clause(SQL('INSERT INTO'), cls._meta.entity, EnclosedClause(*columns), SQL('VALUES'), EnclosedClause(*values)) return cls._meta.database.execute(clause)