def _create_unique_sql(self, model, columns, name=None, condition=None): def create_unique_name(*args, **kwargs): return self.quote_name(self._create_index_name(*args, **kwargs)) table = Table(model._meta.db_table, self.quote_name) if name is None: name = IndexName(model._meta.db_table, columns, '_uniq', create_unique_name) else: name = self.quote_name(name) columns = Columns(table, columns, self.quote_name) if condition: return Statement( self.sql_create_unique_index, table=table, name=name, columns=columns, condition=' WHERE ' + condition, ) if self.connection.features.supports_partial_indexes else None else: return Statement( self.sql_create_unique, table=table, name=name, columns=columns, )
def _create_unique_sql(self, model, columns, name=None, condition=None, deferrable=None): if (deferrable and not getattr(self.connection.features, 'supports_deferrable_unique_constraints', False)): return None def create_unique_name(*args, **kwargs): return self.quote_name(self._create_index_name(*args, **kwargs)) table = Table(model._meta.db_table, self.quote_name) if name is None: name = IndexName(model._meta.db_table, columns, '_uniq', create_unique_name) else: name = self.quote_name(name) columns = Columns(table, columns, self.quote_name) statement_args = { "deferrable": self._deferrable_constraint_sql(deferrable) } if django.VERSION >= (3, 1) else {} if condition: return Statement( self.sql_create_unique_index, table=table, name=name, columns=columns, condition=' WHERE ' + condition, **statement_args ) if self.connection.features.supports_partial_indexes else None else: return Statement( self.sql_create_unique, table=table, name=name, columns=columns, **statement_args )
def _create_index_sql(self, model, fields, *, name=None, suffix='', using='', db_tablespace=None, col_suffixes=(), sql=None, opclasses=(), condition=None): """ Return the SQL statement to create the index for one or several fields. `sql` can be specified if the syntax differs from the standard (GIS indexes, ...). """ tablespace_sql = self._get_index_tablespace_sql(model, fields, db_tablespace=db_tablespace) columns = [field.column for field in fields] sql_create_index = sql or self.sql_create_index table = model._meta.db_table def create_index_name(*args, **kwargs): nonlocal name if name is None: name = self._create_index_name(*args, **kwargs) return self.quote_name(name) return Statement( sql_create_index, table=Table(table, self.quote_name), name=IndexName(table, columns, suffix, create_index_name), using=using, columns=self._index_columns(table, columns, col_suffixes, opclasses), extra=tablespace_sql, condition=(' WHERE ' + condition) if condition else '', )
def create_sql(self, model, schema_editor): self.check_supported(schema_editor) return Statement( "ALTER TABLE %(table)s ADD %(constraint)s", table=Table(model._meta.db_table, schema_editor.quote_name), constraint=self.constraint_sql(model, schema_editor), )
def _create_unique_sql(self, model, columns): table = model._meta.db_table return Statement( self.sql_create_unique, table=Table(table, self.quote_name), name=IndexName(table, columns, '_uniq', self._create_index_name), columns=Columns(table, columns, self.quote_name), )
def _create_fk_sql(self, model, field, suffix): from_table = model._meta.db_table from_column = field.column _, to_table = split_identifier(field.target_field.model._meta.db_table) to_column = field.target_field.column def create_fk_name(*args, **kwargs): return self.quote_name(self._create_index_name(*args, **kwargs)) return Statement( self.sql_create_fk, table=Table(from_table, self.quote_name), name=ForeignKeyName(from_table, [from_column], to_table, [to_column], suffix, create_fk_name), column=Columns(from_table, [from_column], self.quote_name), to_table=Table(field.target_field.model._meta.db_table, self.quote_name), to_column=Columns(field.target_field.model._meta.db_table, [to_column], self.quote_name), deferrable=self.connection.ops.deferrable_sql(), )
def _create_fk_sql(self, model, field, suffix): def create_fk_name(*args, **kwargs): return self.quote_name(self._create_index_name(*args, **kwargs)) table = Table(model._meta.db_table, self.quote_name) name = ForeignKeyName( model._meta.db_table, [field.column], split_identifier(field.target_field.model._meta.db_table)[1], [field.target_field.column], suffix, create_fk_name, ) column = Columns(model._meta.db_table, [field.column], self.quote_name) to_table = Table(field.target_field.model._meta.db_table, self.quote_name) to_column = Columns(field.target_field.model._meta.db_table, [field.target_field.column], self.quote_name) deferrable = self.connection.ops.deferrable_sql() table_name = model._meta.db_table to_table_name = field.target_field.model._meta.db_table if (table_name == to_table_name): return Statement( self.sql_create_fk, table=table, name=name, column=column, to_table=to_table, to_column=to_column, on_update="", deferrable=deferrable, ) else: return Statement( self.sql_create_fk, table=table, name=name, column=column, to_table=to_table, to_column=to_column, on_update="ON UPDATE CASCADE", deferrable=deferrable, )
def remove_sql( self, model: Optional[Type[Model]], schema_editor: Optional[BaseDatabaseSchemaEditor] ) -> Statement: # type: ignore[override] assert model is not None assert schema_editor is not None return Statement( "ALTER TABLE %(table)s ALTER COLUMN %(field_name)s TYPE varchar(63); DROP TYPE %(enum_type)s;", table=Table(model._meta.db_table, schema_editor.quote_name), field_name=schema_editor.quote_name(self.field_name), enum_type=schema_editor.quote_name(self.name), )
def create_sql( self, model: Optional[Type[Model]], schema_editor: Optional[BaseDatabaseSchemaEditor] ) -> Statement: # type: ignore[override] columns = self.members assert model is not None assert schema_editor is not None return Statement( """ DROP TYPE IF EXISTS %(enum_type)s; CREATE TYPE %(enum_type)s AS ENUM (%(columns)s); ALTER TABLE %(table)s ALTER COLUMN %(field_name)s TYPE %(enum_type)s USING %(field_name)s::%(enum_type)s; """, table=Table(model._meta.db_table, schema_editor.quote_name), field_name=schema_editor.quote_name(self.field_name), enum_type=schema_editor.quote_name(self.name), columns=", ".join([f"'{column}'" for column in columns]), )
def constraint_sql(self, model, schema_editor): query = Query(model, alias_cols=False) compiler = query.get_compiler(connection=schema_editor.connection) expressions = self._get_expressions(schema_editor, query) table = model._meta.db_table condition = self._get_condition_sql(compiler, schema_editor, query) include = [ model._meta.get_field(field_name).column for field_name in self.include ] return Statement( self.template, table=Table(table, schema_editor.quote_name), name=schema_editor.quote_name(self.name), index_type=self.index_type, expressions=Expressions( table, expressions, compiler, schema_editor.quote_value ), where=" WHERE (%s)" % condition if condition else "", include=schema_editor._index_include_sql(model, include), deferrable=schema_editor._deferrable_constraint_sql(self.deferrable), )
def _create_index_sql(self, model, fields, suffix="", sql=None): """ Return the SQL statement to create the index for one or several fields. `sql` can be specified if the syntax differs from the standard (GIS indexes, ...). """ tablespace_sql = self._get_index_tablespace_sql(model, fields) columns = [field.column for field in fields] sql_create_index = sql or self.sql_create_index table = model._meta.db_table def create_index_name(*args, **kwargs): return self.quote_name(self._create_index_name(*args, **kwargs)) return Statement( sql_create_index, table=Table(table, self.quote_name), name=IndexName(table, columns, suffix, create_index_name), using='', columns=Columns(table, columns, self.quote_name), extra=tablespace_sql, )
class TableTests(SimpleTestCase): def setUp(self): self.reference = Table('table', lambda table: table.upper()) def test_references_table(self): self.assertIs(self.reference.references_table('table'), True) self.assertIs(self.reference.references_table('other'), False) def test_rename_table_references(self): self.reference.rename_table_references('other', 'table') self.assertIs(self.reference.references_table('table'), True) self.assertIs(self.reference.references_table('other'), False) self.reference.rename_table_references('table', 'other') self.assertIs(self.reference.references_table('table'), False) self.assertIs(self.reference.references_table('other'), True) def test_repr(self): self.assertEqual(repr(self.reference), "<Table 'TABLE'>") def test_str(self): self.assertEqual(str(self.reference), 'TABLE')
class TableTests(SimpleTestCase): def setUp(self): self.reference = Table("table", lambda table: table.upper()) def test_references_table(self): self.assertIs(self.reference.references_table("table"), True) self.assertIs(self.reference.references_table("other"), False) def test_rename_table_references(self): self.reference.rename_table_references("other", "table") self.assertIs(self.reference.references_table("table"), True) self.assertIs(self.reference.references_table("other"), False) self.reference.rename_table_references("table", "other") self.assertIs(self.reference.references_table("table"), False) self.assertIs(self.reference.references_table("other"), True) def test_repr(self): self.assertEqual(repr(self.reference), "<Table 'TABLE'>") def test_str(self): self.assertEqual(str(self.reference), "TABLE")
class TableTests(SimpleTestCase): def setUp(self): self.reference = Table('table', lambda table: table.upper()) def test_references_table(self): self.assertIs(self.reference.references_table('table'), True) self.assertIs(self.reference.references_table('other'), False) def test_rename_table_references(self): self.reference.rename_table_references('other', 'table') self.assertIs(self.reference.references_table('table'), True) self.assertIs(self.reference.references_table('other'), False) self.reference.rename_table_references('table', 'other') self.assertIs(self.reference.references_table('table'), False) self.assertIs(self.reference.references_table('other'), True) def test_repr(self): self.assertEqual(repr(self.reference), "<Table 'TABLE'>") def test_str(self): self.assertEqual(str(self.reference), 'TABLE')
def create_sql(self, model, schema_editor): return Statement( 'ALTER TABLE %(table)s ADD %(constraint)s', table=Table(model._meta.db_table, schema_editor.quote_name), constraint=self.constraint_sql(model, schema_editor), )
def setUp(self): self.reference = Table('table', lambda table: table.upper())
def _db_table_delete_constraint_sql(self, template, db_table, name): return Statement( template, table=Table(db_table, self.quote_name), name=self.quote_name(name), )
def setUp(self): self.reference = Table('table', lambda table: table.upper())