summaryrefslogtreecommitdiff
path: root/tests/schema/tests.py
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /tests/schema/tests.py
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/schema/tests.py')
-rw-r--r--tests/schema/tests.py2190
1 files changed, 1291 insertions, 899 deletions
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index 60e69503cc..267a7c971b 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -7,40 +7,85 @@ from unittest import mock
from django.core.exceptions import FieldError
from django.core.management.color import no_style
from django.db import (
- DatabaseError, DataError, IntegrityError, OperationalError, connection,
+ DatabaseError,
+ DataError,
+ IntegrityError,
+ OperationalError,
+ connection,
)
from django.db.models import (
- CASCADE, PROTECT, AutoField, BigAutoField, BigIntegerField, BinaryField,
- BooleanField, CharField, CheckConstraint, DateField, DateTimeField,
- DecimalField, DurationField, F, FloatField, ForeignKey, ForeignObject,
- Index, IntegerField, JSONField, ManyToManyField, Model, OneToOneField,
- OrderBy, PositiveIntegerField, Q, SlugField, SmallAutoField,
- SmallIntegerField, TextField, TimeField, UniqueConstraint, UUIDField,
+ CASCADE,
+ PROTECT,
+ AutoField,
+ BigAutoField,
+ BigIntegerField,
+ BinaryField,
+ BooleanField,
+ CharField,
+ CheckConstraint,
+ DateField,
+ DateTimeField,
+ DecimalField,
+ DurationField,
+ F,
+ FloatField,
+ ForeignKey,
+ ForeignObject,
+ Index,
+ IntegerField,
+ JSONField,
+ ManyToManyField,
+ Model,
+ OneToOneField,
+ OrderBy,
+ PositiveIntegerField,
+ Q,
+ SlugField,
+ SmallAutoField,
+ SmallIntegerField,
+ TextField,
+ TimeField,
+ UniqueConstraint,
+ UUIDField,
Value,
)
from django.db.models.fields.json import KeyTextTransform
from django.db.models.functions import Abs, Cast, Collate, Lower, Random, Upper
from django.db.models.indexes import IndexExpression
from django.db.transaction import TransactionManagementError, atomic
-from django.test import (
- TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature,
-)
-from django.test.utils import (
- CaptureQueriesContext, isolate_apps, register_lookup,
-)
+from django.test import TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature
+from django.test.utils import CaptureQueriesContext, isolate_apps, register_lookup
from django.utils import timezone
-from .fields import (
- CustomManyToManyField, InheritedManyToManyField, MediumBlobField,
-)
+from .fields import CustomManyToManyField, InheritedManyToManyField, MediumBlobField
from .models import (
- Author, AuthorCharFieldWithIndex, AuthorTextFieldWithIndex,
- AuthorWithDefaultHeight, AuthorWithEvenLongerName, AuthorWithIndexedName,
- AuthorWithIndexedNameAndBirthday, AuthorWithUniqueName,
- AuthorWithUniqueNameAndBirthday, Book, BookForeignObj, BookWeak,
- BookWithLongName, BookWithO2O, BookWithoutAuthor, BookWithSlug, IntegerPK,
- Node, Note, NoteRename, Tag, TagIndexed, TagM2MTest, TagUniqueRename,
- Thing, UniqueTest, new_apps,
+ Author,
+ AuthorCharFieldWithIndex,
+ AuthorTextFieldWithIndex,
+ AuthorWithDefaultHeight,
+ AuthorWithEvenLongerName,
+ AuthorWithIndexedName,
+ AuthorWithIndexedNameAndBirthday,
+ AuthorWithUniqueName,
+ AuthorWithUniqueNameAndBirthday,
+ Book,
+ BookForeignObj,
+ BookWeak,
+ BookWithLongName,
+ BookWithO2O,
+ BookWithoutAuthor,
+ BookWithSlug,
+ IntegerPK,
+ Node,
+ Note,
+ NoteRename,
+ Tag,
+ TagIndexed,
+ TagM2MTest,
+ TagUniqueRename,
+ Thing,
+ UniqueTest,
+ new_apps,
)
@@ -56,10 +101,25 @@ class SchemaTests(TransactionTestCase):
available_apps = []
models = [
- Author, AuthorCharFieldWithIndex, AuthorTextFieldWithIndex,
- AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book, BookWeak,
- BookWithLongName, BookWithO2O, BookWithSlug, IntegerPK, Node, Note,
- Tag, TagIndexed, TagM2MTest, TagUniqueRename, Thing, UniqueTest,
+ Author,
+ AuthorCharFieldWithIndex,
+ AuthorTextFieldWithIndex,
+ AuthorWithDefaultHeight,
+ AuthorWithEvenLongerName,
+ Book,
+ BookWeak,
+ BookWithLongName,
+ BookWithO2O,
+ BookWithSlug,
+ IntegerPK,
+ Node,
+ Note,
+ Tag,
+ TagIndexed,
+ TagM2MTest,
+ TagUniqueRename,
+ Thing,
+ UniqueTest,
]
# Utility functions
@@ -78,13 +138,13 @@ class SchemaTests(TransactionTestCase):
new_apps.clear_cache()
for model in new_apps.get_models():
model._meta._expire_cache()
- if 'schema' in new_apps.all_models:
+ if "schema" in new_apps.all_models:
for model in self.local_models:
for many_to_many in model._meta.many_to_many:
through = many_to_many.remote_field.through
if through and through._meta.auto_created:
- del new_apps.all_models['schema'][through._meta.model_name]
- del new_apps.all_models['schema'][model._meta.model_name]
+ del new_apps.all_models["schema"][through._meta.model_name]
+ del new_apps.all_models["schema"][model._meta.model_name]
if self.isolated_local_models:
with connection.schema_editor() as editor:
for model in self.isolated_local_models:
@@ -132,17 +192,21 @@ class SchemaTests(TransactionTestCase):
"""
with connection.cursor() as cursor:
return [
- c['columns'][0]
- for c in connection.introspection.get_constraints(cursor, table).values()
- if c['index'] and len(c['columns']) == 1
+ c["columns"][0]
+ for c in connection.introspection.get_constraints(
+ cursor, table
+ ).values()
+ if c["index"] and len(c["columns"]) == 1
]
def get_uniques(self, table):
with connection.cursor() as cursor:
return [
- c['columns'][0]
- for c in connection.introspection.get_constraints(cursor, table).values()
- if c['unique'] and len(c['columns']) == 1
+ c["columns"][0]
+ for c in connection.introspection.get_constraints(
+ cursor, table
+ ).values()
+ if c["unique"] and len(c["columns"]) == 1
]
def get_constraints(self, table):
@@ -156,15 +220,24 @@ class SchemaTests(TransactionTestCase):
constraints = self.get_constraints(model._meta.db_table)
constraints_for_column = []
for name, details in constraints.items():
- if details['columns'] == [column_name]:
+ if details["columns"] == [column_name]:
constraints_for_column.append(name)
return sorted(constraints_for_column)
- def check_added_field_default(self, schema_editor, model, field, field_name, expected_default,
- cast_function=None):
+ def check_added_field_default(
+ self,
+ schema_editor,
+ model,
+ field,
+ field_name,
+ expected_default,
+ cast_function=None,
+ ):
with connection.cursor() as cursor:
schema_editor.add_field(model, field)
- cursor.execute("SELECT {} FROM {};".format(field_name, model._meta.db_table))
+ cursor.execute(
+ "SELECT {} FROM {};".format(field_name, model._meta.db_table)
+ )
database_default = cursor.fetchall()[0][0]
if cast_function and type(database_default) != type(expected_default):
database_default = cast_function(database_default)
@@ -179,15 +252,15 @@ class SchemaTests(TransactionTestCase):
"""
with connection.cursor() as cursor:
constraints = connection.introspection.get_constraints(cursor, table)
- counts = {'fks': 0, 'uniques': 0, 'indexes': 0}
+ counts = {"fks": 0, "uniques": 0, "indexes": 0}
for c in constraints.values():
- if c['columns'] == [column]:
- if c['foreign_key'] == fk_to:
- counts['fks'] += 1
- if c['unique']:
- counts['uniques'] += 1
- elif c['index']:
- counts['indexes'] += 1
+ if c["columns"] == [column]:
+ if c["foreign_key"] == fk_to:
+ counts["fks"] += 1
+ if c["unique"]:
+ counts["uniques"] += 1
+ elif c["index"]:
+ counts["indexes"] += 1
return counts
def get_column_collation(self, table, column):
@@ -201,10 +274,12 @@ class SchemaTests(TransactionTestCase):
def assertIndexOrder(self, table, index, order):
constraints = self.get_constraints(table)
self.assertIn(index, constraints)
- index_orders = constraints[index]['orders']
- self.assertTrue(all(val == expected for val, expected in zip(index_orders, order)))
+ index_orders = constraints[index]["orders"]
+ self.assertTrue(
+ all(val == expected for val, expected in zip(index_orders, order))
+ )
- def assertForeignKeyExists(self, model, column, expected_fk_table, field='id'):
+ def assertForeignKeyExists(self, model, column, expected_fk_table, field="id"):
"""
Fail if the FK constraint on `model.Meta.db_table`.`column` to
`expected_fk_table`.id doesn't exist.
@@ -212,8 +287,8 @@ class SchemaTests(TransactionTestCase):
constraints = self.get_constraints(model._meta.db_table)
constraint_fk = None
for details in constraints.values():
- if details['columns'] == [column] and details['foreign_key']:
- constraint_fk = details['foreign_key']
+ if details["columns"] == [column] and details["foreign_key"]:
+ constraint_fk = details["foreign_key"]
break
self.assertEqual(constraint_fk, (expected_fk_table, field))
@@ -239,7 +314,7 @@ class SchemaTests(TransactionTestCase):
with self.assertRaises(DatabaseError):
list(Author.objects.all())
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_fk(self):
"Creating tables out of FK order, then repointing, works"
# Create the table
@@ -263,124 +338,138 @@ class SchemaTests(TransactionTestCase):
new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.alter_field(Book, old_field, new_field, strict=True)
- self.assertForeignKeyExists(Book, 'author_id', 'schema_tag')
+ self.assertForeignKeyExists(Book, "author_id", "schema_tag")
- @skipUnlessDBFeature('can_create_inline_fk')
+ @skipUnlessDBFeature("can_create_inline_fk")
def test_inline_fk(self):
# Create some tables.
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(Book)
editor.create_model(Note)
- self.assertForeignKeyNotExists(Note, 'book_id', 'schema_book')
+ self.assertForeignKeyNotExists(Note, "book_id", "schema_book")
# Add a foreign key from one to the other.
with connection.schema_editor() as editor:
new_field = ForeignKey(Book, CASCADE)
- new_field.set_attributes_from_name('book')
+ new_field.set_attributes_from_name("book")
editor.add_field(Note, new_field)
- self.assertForeignKeyExists(Note, 'book_id', 'schema_book')
+ self.assertForeignKeyExists(Note, "book_id", "schema_book")
# Creating a FK field with a constraint uses a single statement without
# a deferred ALTER TABLE.
- self.assertFalse([
- sql for sql in (str(statement) for statement in editor.deferred_sql)
- if sql.startswith('ALTER TABLE') and 'ADD CONSTRAINT' in sql
- ])
+ self.assertFalse(
+ [
+ sql
+ for sql in (str(statement) for statement in editor.deferred_sql)
+ if sql.startswith("ALTER TABLE") and "ADD CONSTRAINT" in sql
+ ]
+ )
- @skipUnlessDBFeature('can_create_inline_fk')
+ @skipUnlessDBFeature("can_create_inline_fk")
def test_add_inline_fk_update_data(self):
with connection.schema_editor() as editor:
editor.create_model(Node)
# Add an inline foreign key and update data in the same transaction.
- new_field = ForeignKey(Node, CASCADE, related_name='new_fk', null=True)
- new_field.set_attributes_from_name('new_parent_fk')
+ new_field = ForeignKey(Node, CASCADE, related_name="new_fk", null=True)
+ new_field.set_attributes_from_name("new_parent_fk")
parent = Node.objects.create()
with connection.schema_editor() as editor:
editor.add_field(Node, new_field)
- editor.execute('UPDATE schema_node SET new_parent_fk_id = %s;', [parent.pk])
+ editor.execute("UPDATE schema_node SET new_parent_fk_id = %s;", [parent.pk])
assertIndex = (
self.assertIn
if connection.features.indexes_foreign_keys
else self.assertNotIn
)
- assertIndex('new_parent_fk_id', self.get_indexes(Node._meta.db_table))
+ assertIndex("new_parent_fk_id", self.get_indexes(Node._meta.db_table))
@skipUnlessDBFeature(
- 'can_create_inline_fk',
- 'allows_multiple_constraints_on_same_fields',
+ "can_create_inline_fk",
+ "allows_multiple_constraints_on_same_fields",
)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_add_inline_fk_index_update_data(self):
class Node(Model):
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Node)
# Add an inline foreign key, update data, and an index in the same
# transaction.
- new_field = ForeignKey(Node, CASCADE, related_name='new_fk', null=True)
- new_field.set_attributes_from_name('new_parent_fk')
+ new_field = ForeignKey(Node, CASCADE, related_name="new_fk", null=True)
+ new_field.set_attributes_from_name("new_parent_fk")
parent = Node.objects.create()
with connection.schema_editor() as editor:
editor.add_field(Node, new_field)
Node._meta.add_field(new_field)
- editor.execute('UPDATE schema_node SET new_parent_fk_id = %s;', [parent.pk])
- editor.add_index(Node, Index(fields=['new_parent_fk'], name='new_parent_inline_fk_idx'))
- self.assertIn('new_parent_fk_id', self.get_indexes(Node._meta.db_table))
+ editor.execute("UPDATE schema_node SET new_parent_fk_id = %s;", [parent.pk])
+ editor.add_index(
+ Node, Index(fields=["new_parent_fk"], name="new_parent_inline_fk_idx")
+ )
+ self.assertIn("new_parent_fk_id", self.get_indexes(Node._meta.db_table))
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_char_field_with_db_index_to_fk(self):
# Create the table
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(AuthorCharFieldWithIndex)
# Change CharField to FK
- old_field = AuthorCharFieldWithIndex._meta.get_field('char_field')
+ old_field = AuthorCharFieldWithIndex._meta.get_field("char_field")
new_field = ForeignKey(Author, CASCADE, blank=True)
- new_field.set_attributes_from_name('char_field')
+ new_field.set_attributes_from_name("char_field")
with connection.schema_editor() as editor:
- editor.alter_field(AuthorCharFieldWithIndex, old_field, new_field, strict=True)
- self.assertForeignKeyExists(AuthorCharFieldWithIndex, 'char_field_id', 'schema_author')
+ editor.alter_field(
+ AuthorCharFieldWithIndex, old_field, new_field, strict=True
+ )
+ self.assertForeignKeyExists(
+ AuthorCharFieldWithIndex, "char_field_id", "schema_author"
+ )
- @skipUnlessDBFeature('supports_foreign_keys')
- @skipUnlessDBFeature('supports_index_on_text_field')
+ @skipUnlessDBFeature("supports_foreign_keys")
+ @skipUnlessDBFeature("supports_index_on_text_field")
def test_text_field_with_db_index_to_fk(self):
# Create the table
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(AuthorTextFieldWithIndex)
# Change TextField to FK
- old_field = AuthorTextFieldWithIndex._meta.get_field('text_field')
+ old_field = AuthorTextFieldWithIndex._meta.get_field("text_field")
new_field = ForeignKey(Author, CASCADE, blank=True)
- new_field.set_attributes_from_name('text_field')
+ new_field.set_attributes_from_name("text_field")
with connection.schema_editor() as editor:
- editor.alter_field(AuthorTextFieldWithIndex, old_field, new_field, strict=True)
- self.assertForeignKeyExists(AuthorTextFieldWithIndex, 'text_field_id', 'schema_author')
+ editor.alter_field(
+ AuthorTextFieldWithIndex, old_field, new_field, strict=True
+ )
+ self.assertForeignKeyExists(
+ AuthorTextFieldWithIndex, "text_field_id", "schema_author"
+ )
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_char_field_pk_to_auto_field(self):
class Foo(Model):
id = CharField(max_length=255, primary_key=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Foo)
self.isolated_local_models = [Foo]
- old_field = Foo._meta.get_field('id')
+ old_field = Foo._meta.get_field("id")
new_field = AutoField(primary_key=True)
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
new_field.model = Foo
with connection.schema_editor() as editor:
editor.alter_field(Foo, old_field, new_field, strict=True)
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_fk_to_proxy(self):
"Creating a FK to a proxy model creates database constraints."
+
class AuthorProxy(Author):
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
proxy = True
@@ -388,7 +477,7 @@ class SchemaTests(TransactionTestCase):
author = ForeignKey(AuthorProxy, on_delete=CASCADE)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
self.local_models = [AuthorProxy, AuthorRef]
@@ -397,9 +486,9 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(AuthorRef)
- self.assertForeignKeyExists(AuthorRef, 'author_id', 'schema_author')
+ self.assertForeignKeyExists(AuthorRef, "author_id", "schema_author")
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_fk_db_constraint(self):
"The db_constraint parameter is respected"
# Create the table
@@ -411,63 +500,64 @@ class SchemaTests(TransactionTestCase):
list(Author.objects.all())
list(Tag.objects.all())
list(BookWeak.objects.all())
- self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author')
+ self.assertForeignKeyNotExists(BookWeak, "author_id", "schema_author")
# Make a db_constraint=False FK
new_field = ForeignKey(Tag, CASCADE, db_constraint=False)
new_field.set_attributes_from_name("tag")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
- self.assertForeignKeyNotExists(Author, 'tag_id', 'schema_tag')
+ self.assertForeignKeyNotExists(Author, "tag_id", "schema_tag")
# Alter to one with a constraint
new_field2 = ForeignKey(Tag, CASCADE)
new_field2.set_attributes_from_name("tag")
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, new_field2, strict=True)
- self.assertForeignKeyExists(Author, 'tag_id', 'schema_tag')
+ self.assertForeignKeyExists(Author, "tag_id", "schema_tag")
# Alter to one without a constraint again
new_field2 = ForeignKey(Tag, CASCADE)
new_field2.set_attributes_from_name("tag")
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field2, new_field, strict=True)
- self.assertForeignKeyNotExists(Author, 'tag_id', 'schema_tag')
+ self.assertForeignKeyNotExists(Author, "tag_id", "schema_tag")
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_no_db_constraint_added_during_primary_key_change(self):
"""
When a primary key that's pointed to by a ForeignKey with
db_constraint=False is altered, a foreign key constraint isn't added.
"""
+
class Author(Model):
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class BookWeak(Model):
author = ForeignKey(Author, CASCADE, db_constraint=False)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(BookWeak)
- self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author')
- old_field = Author._meta.get_field('id')
+ self.assertForeignKeyNotExists(BookWeak, "author_id", "schema_author")
+ old_field = Author._meta.get_field("id")
new_field = BigAutoField(primary_key=True)
new_field.model = Author
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
# @isolate_apps() and inner models are needed to have the model
# relations populated, otherwise this doesn't act as a regression test.
self.assertEqual(len(new_field.model._meta.related_objects), 1)
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
- self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author')
+ self.assertForeignKeyNotExists(BookWeak, "author_id", "schema_author")
def _test_m2m_db_constraint(self, M2MFieldClass):
class LocalAuthorWithM2M(Model):
name = CharField(max_length=255)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
self.local_models = [LocalAuthorWithM2M]
@@ -485,17 +575,19 @@ class SchemaTests(TransactionTestCase):
# Add the field
with connection.schema_editor() as editor:
editor.add_field(LocalAuthorWithM2M, new_field)
- self.assertForeignKeyNotExists(new_field.remote_field.through, 'tag_id', 'schema_tag')
+ self.assertForeignKeyNotExists(
+ new_field.remote_field.through, "tag_id", "schema_tag"
+ )
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_m2m_db_constraint(self):
self._test_m2m_db_constraint(ManyToManyField)
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_m2m_db_constraint_custom(self):
self._test_m2m_db_constraint(CustomManyToManyField)
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_m2m_db_constraint_inherited(self):
self._test_m2m_db_constraint(InheritedManyToManyField)
@@ -512,24 +604,29 @@ class SchemaTests(TransactionTestCase):
# Add the new field
new_field = IntegerField(null=True)
new_field.set_attributes_from_name("age")
- with CaptureQueriesContext(connection) as ctx, connection.schema_editor() as editor:
+ with CaptureQueriesContext(
+ connection
+ ) as ctx, connection.schema_editor() as editor:
editor.add_field(Author, new_field)
drop_default_sql = editor.sql_alter_column_no_default % {
- 'column': editor.quote_name(new_field.name),
+ "column": editor.quote_name(new_field.name),
}
- self.assertFalse(any(drop_default_sql in query['sql'] for query in ctx.captured_queries))
+ self.assertFalse(
+ any(drop_default_sql in query["sql"] for query in ctx.captured_queries)
+ )
# Table is not rebuilt.
- self.assertIs(any(
- 'CREATE TABLE' in query['sql']
- for query in ctx.captured_queries
- ), False)
- self.assertIs(any(
- 'DROP TABLE' in query['sql']
- for query in ctx.captured_queries
- ), False)
+ self.assertIs(
+ any("CREATE TABLE" in query["sql"] for query in ctx.captured_queries), False
+ )
+ self.assertIs(
+ any("DROP TABLE" in query["sql"] for query in ctx.captured_queries), False
+ )
columns = self.column_classes(Author)
- self.assertEqual(columns['age'][0], connection.features.introspected_field_types['IntegerField'])
- self.assertTrue(columns['age'][1][6])
+ self.assertEqual(
+ columns["age"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
+ self.assertTrue(columns["age"][1][6])
def test_add_field_remove_field(self):
"""
@@ -539,7 +636,7 @@ class SchemaTests(TransactionTestCase):
# Create a table with a unique constraint on the slug field.
editor.create_model(Tag)
# Remove the slug column.
- editor.remove_field(Tag, Tag._meta.get_field('slug'))
+ editor.remove_field(Tag, Tag._meta.get_field("slug"))
self.assertEqual(editor.deferred_sql, [])
def test_add_field_temp_default(self):
@@ -561,9 +658,14 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
columns = self.column_classes(Author)
- self.assertEqual(columns['surname'][0], connection.features.introspected_field_types['CharField'])
- self.assertEqual(columns['surname'][1][6],
- connection.features.interprets_empty_strings_as_nulls)
+ self.assertEqual(
+ columns["surname"][0],
+ connection.features.introspected_field_types["CharField"],
+ )
+ self.assertEqual(
+ columns["surname"][1][6],
+ connection.features.interprets_empty_strings_as_nulls,
+ )
def test_add_field_temp_default_boolean(self):
"""
@@ -586,8 +688,10 @@ class SchemaTests(TransactionTestCase):
editor.add_field(Author, new_field)
columns = self.column_classes(Author)
# BooleanField are stored as TINYINT(1) on MySQL.
- field_type = columns['awesome'][0]
- self.assertEqual(field_type, connection.features.introspected_field_types['BooleanField'])
+ field_type = columns["awesome"][0]
+ self.assertEqual(
+ field_type, connection.features.introspected_field_types["BooleanField"]
+ )
def test_add_field_default_transform(self):
"""
@@ -619,8 +723,10 @@ class SchemaTests(TransactionTestCase):
editor.add_field(Author, new_field)
# Ensure the field is there
columns = self.column_classes(Author)
- field_type, field_info = columns['thing']
- self.assertEqual(field_type, connection.features.introspected_field_types['IntegerField'])
+ field_type, field_info = columns["thing"]
+ self.assertEqual(
+ field_type, connection.features.introspected_field_types["IntegerField"]
+ )
# Make sure the values were transformed correctly
self.assertEqual(Author.objects.extra(where=["thing = 1"]).count(), 2)
@@ -629,12 +735,12 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Author)
editor.create_model(Note)
new_field = OneToOneField(Note, CASCADE, null=True)
- new_field.set_attributes_from_name('note')
+ new_field.set_attributes_from_name("note")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
columns = self.column_classes(Author)
- self.assertIn('note_id', columns)
- self.assertTrue(columns['note_id'][1][6])
+ self.assertIn("note_id", columns)
+ self.assertTrue(columns["note_id"][1][6])
def test_add_field_binary(self):
"""
@@ -651,22 +757,22 @@ class SchemaTests(TransactionTestCase):
columns = self.column_classes(Author)
# MySQL annoyingly uses the same backend, so it'll come back as one of
# these two types.
- self.assertIn(columns['bits'][0], ("BinaryField", "TextField"))
+ self.assertIn(columns["bits"][0], ("BinaryField", "TextField"))
def test_add_field_durationfield_with_default(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
new_field = DurationField(default=datetime.timedelta(minutes=10))
- new_field.set_attributes_from_name('duration')
+ new_field.set_attributes_from_name("duration")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
columns = self.column_classes(Author)
self.assertEqual(
- columns['duration'][0],
- connection.features.introspected_field_types['DurationField'],
+ columns["duration"][0],
+ connection.features.introspected_field_types["DurationField"],
)
- @unittest.skipUnless(connection.vendor == 'mysql', "MySQL specific")
+ @unittest.skipUnless(connection.vendor == "mysql", "MySQL specific")
def test_add_binaryfield_mediumblob(self):
"""
Test adding a custom-sized binary field on MySQL (#24846).
@@ -675,13 +781,13 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Add the new field with default
- new_field = MediumBlobField(blank=True, default=b'123')
- new_field.set_attributes_from_name('bits')
+ new_field = MediumBlobField(blank=True, default=b"123")
+ new_field.set_attributes_from_name("bits")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
columns = self.column_classes(Author)
# Introspection treats BLOBs as TextFields
- self.assertEqual(columns['bits'][0], "TextField")
+ self.assertEqual(columns["bits"][0], "TextField")
def test_alter(self):
"""
@@ -692,8 +798,14 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Author)
# Ensure the field is right to begin with
columns = self.column_classes(Author)
- self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField'])
- self.assertEqual(bool(columns['name'][1][6]), bool(connection.features.interprets_empty_strings_as_nulls))
+ self.assertEqual(
+ columns["name"][0],
+ connection.features.introspected_field_types["CharField"],
+ )
+ self.assertEqual(
+ bool(columns["name"][1][6]),
+ bool(connection.features.interprets_empty_strings_as_nulls),
+ )
# Alter the name field to a TextField
old_field = Author._meta.get_field("name")
new_field = TextField(null=True)
@@ -701,25 +813,28 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
columns = self.column_classes(Author)
- self.assertEqual(columns['name'][0], "TextField")
- self.assertTrue(columns['name'][1][6])
+ self.assertEqual(columns["name"][0], "TextField")
+ self.assertTrue(columns["name"][1][6])
# Change nullability again
new_field2 = TextField(null=False)
new_field2.set_attributes_from_name("name")
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, new_field2, strict=True)
columns = self.column_classes(Author)
- self.assertEqual(columns['name'][0], "TextField")
- self.assertEqual(bool(columns['name'][1][6]), bool(connection.features.interprets_empty_strings_as_nulls))
+ self.assertEqual(columns["name"][0], "TextField")
+ self.assertEqual(
+ bool(columns["name"][1][6]),
+ bool(connection.features.interprets_empty_strings_as_nulls),
+ )
def test_alter_auto_field_to_integer_field(self):
# Create the table
with connection.schema_editor() as editor:
editor.create_model(Author)
# Change AutoField to IntegerField
- old_field = Author._meta.get_field('id')
+ old_field = Author._meta.get_field("id")
new_field = IntegerField(primary_key=True)
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
new_field.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
@@ -734,29 +849,29 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Change AutoField to CharField
- old_field = Author._meta.get_field('id')
+ old_field = Author._meta.get_field("id")
new_field = CharField(primary_key=True, max_length=50)
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
new_field.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_alter_auto_field_quoted_db_column(self):
class Foo(Model):
id = AutoField(primary_key=True, db_column='"quoted_id"')
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Foo)
self.isolated_local_models = [Foo]
- old_field = Foo._meta.get_field('id')
+ old_field = Foo._meta.get_field("id")
new_field = BigAutoField(primary_key=True)
new_field.model = Foo
new_field.db_column = '"quoted_id"'
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
with connection.schema_editor() as editor:
editor.alter_field(Foo, old_field, new_field, strict=True)
Foo.objects.create()
@@ -766,35 +881,35 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Change UUIDField to primary key.
- old_field = Author._meta.get_field('uuid')
+ old_field = Author._meta.get_field("uuid")
new_field = UUIDField(primary_key=True)
- new_field.set_attributes_from_name('uuid')
+ new_field.set_attributes_from_name("uuid")
new_field.model = Author
with connection.schema_editor() as editor:
- editor.remove_field(Author, Author._meta.get_field('id'))
+ editor.remove_field(Author, Author._meta.get_field("id"))
editor.alter_field(Author, old_field, new_field, strict=True)
# Redundant unique constraint is not added.
count = self.get_constraints_count(
Author._meta.db_table,
- Author._meta.get_field('uuid').column,
+ Author._meta.get_field("uuid").column,
None,
)
- self.assertLessEqual(count['uniques'], 1)
+ self.assertLessEqual(count["uniques"], 1)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_alter_primary_key_quoted_db_table(self):
class Foo(Model):
class Meta:
- app_label = 'schema'
+ app_label = "schema"
db_table = '"foo"'
with connection.schema_editor() as editor:
editor.create_model(Foo)
self.isolated_local_models = [Foo]
- old_field = Foo._meta.get_field('id')
+ old_field = Foo._meta.get_field("id")
new_field = BigAutoField(primary_key=True)
new_field.model = Foo
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
with connection.schema_editor() as editor:
editor.alter_field(Foo, old_field, new_field, strict=True)
Foo.objects.create()
@@ -814,13 +929,13 @@ class SchemaTests(TransactionTestCase):
def test_alter_text_field_to_not_null_with_default_value(self):
with connection.schema_editor() as editor:
editor.create_model(Note)
- old_field = Note._meta.get_field('address')
- new_field = TextField(blank=True, default='', null=False)
- new_field.set_attributes_from_name('address')
+ old_field = Note._meta.get_field("address")
+ new_field = TextField(blank=True, default="", null=False)
+ new_field.set_attributes_from_name("address")
with connection.schema_editor() as editor:
editor.alter_field(Note, old_field, new_field, strict=True)
- @skipUnlessDBFeature('can_defer_constraint_checks', 'can_rollback_ddl')
+ @skipUnlessDBFeature("can_defer_constraint_checks", "can_rollback_ddl")
def test_alter_fk_checks_deferred_constraints(self):
"""
#25492 - Altering a foreign key's structure and data in the same
@@ -828,9 +943,9 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(Node)
- old_field = Node._meta.get_field('parent')
+ old_field = Node._meta.get_field("parent")
new_field = ForeignKey(Node, CASCADE)
- new_field.set_attributes_from_name('parent')
+ new_field.set_attributes_from_name("parent")
parent = Node.objects.create()
with connection.schema_editor() as editor:
# Update the parent FK to create a deferred constraint check.
@@ -843,15 +958,15 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(Note)
- Note.objects.create(info='1988-05-05')
- old_field = Note._meta.get_field('info')
+ Note.objects.create(info="1988-05-05")
+ old_field = Note._meta.get_field("info")
new_field = DateField(blank=True)
- new_field.set_attributes_from_name('info')
+ new_field.set_attributes_from_name("info")
with connection.schema_editor() as editor:
editor.alter_field(Note, old_field, new_field, strict=True)
# Make sure the field isn't nullable
columns = self.column_classes(Note)
- self.assertFalse(columns['info'][1][6])
+ self.assertFalse(columns["info"][1][6])
def test_alter_text_field_to_datetime_field(self):
"""
@@ -859,15 +974,15 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(Note)
- Note.objects.create(info='1988-05-05 3:16:17.4567')
- old_field = Note._meta.get_field('info')
+ Note.objects.create(info="1988-05-05 3:16:17.4567")
+ old_field = Note._meta.get_field("info")
new_field = DateTimeField(blank=True)
- new_field.set_attributes_from_name('info')
+ new_field.set_attributes_from_name("info")
with connection.schema_editor() as editor:
editor.alter_field(Note, old_field, new_field, strict=True)
# Make sure the field isn't nullable
columns = self.column_classes(Note)
- self.assertFalse(columns['info'][1][6])
+ self.assertFalse(columns["info"][1][6])
def test_alter_text_field_to_time_field(self):
"""
@@ -875,17 +990,17 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(Note)
- Note.objects.create(info='3:16:17.4567')
- old_field = Note._meta.get_field('info')
+ Note.objects.create(info="3:16:17.4567")
+ old_field = Note._meta.get_field("info")
new_field = TimeField(blank=True)
- new_field.set_attributes_from_name('info')
+ new_field.set_attributes_from_name("info")
with connection.schema_editor() as editor:
editor.alter_field(Note, old_field, new_field, strict=True)
# Make sure the field isn't nullable
columns = self.column_classes(Note)
- self.assertFalse(columns['info'][1][6])
+ self.assertFalse(columns["info"][1][6])
- @skipIfDBFeature('interprets_empty_strings_as_nulls')
+ @skipIfDBFeature("interprets_empty_strings_as_nulls")
def test_alter_textual_field_keep_null_status(self):
"""
Changing a field type shouldn't affect the not null status.
@@ -902,7 +1017,7 @@ class SchemaTests(TransactionTestCase):
with self.assertRaises(IntegrityError):
Note.objects.create(info=None)
- @skipUnlessDBFeature('interprets_empty_strings_as_nulls')
+ @skipUnlessDBFeature("interprets_empty_strings_as_nulls")
def test_alter_textual_field_not_null_to_null(self):
"""
Nullability for textual fields is preserved on databases that
@@ -912,16 +1027,16 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Author)
columns = self.column_classes(Author)
# Field is nullable.
- self.assertTrue(columns['uuid'][1][6])
+ self.assertTrue(columns["uuid"][1][6])
# Change to NOT NULL.
- old_field = Author._meta.get_field('uuid')
+ old_field = Author._meta.get_field("uuid")
new_field = SlugField(null=False, blank=True)
- new_field.set_attributes_from_name('uuid')
+ new_field.set_attributes_from_name("uuid")
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
columns = self.column_classes(Author)
# Nullability is preserved.
- self.assertTrue(columns['uuid'][1][6])
+ self.assertTrue(columns["uuid"][1][6])
def test_alter_numeric_field_keep_null_status(self):
"""
@@ -930,14 +1045,14 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(UniqueTest)
with self.assertRaises(IntegrityError):
- UniqueTest.objects.create(year=None, slug='aaa')
+ UniqueTest.objects.create(year=None, slug="aaa")
old_field = UniqueTest._meta.get_field("year")
new_field = BigIntegerField()
new_field.set_attributes_from_name("year")
with connection.schema_editor() as editor:
editor.alter_field(UniqueTest, old_field, new_field, strict=True)
with self.assertRaises(IntegrityError):
- UniqueTest.objects.create(year=None, slug='bbb')
+ UniqueTest.objects.create(year=None, slug="bbb")
def test_alter_null_to_not_null(self):
"""
@@ -948,13 +1063,13 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Author)
# Ensure the field is right to begin with
columns = self.column_classes(Author)
- self.assertTrue(columns['height'][1][6])
+ self.assertTrue(columns["height"][1][6])
# Create some test data
- Author.objects.create(name='Not null author', height=12)
- Author.objects.create(name='Null author')
+ Author.objects.create(name="Not null author", height=12)
+ Author.objects.create(name="Null author")
# Verify null value
- self.assertEqual(Author.objects.get(name='Not null author').height, 12)
- self.assertIsNone(Author.objects.get(name='Null author').height)
+ self.assertEqual(Author.objects.get(name="Not null author").height, 12)
+ self.assertIsNone(Author.objects.get(name="Null author").height)
# Alter the height field to NOT NULL with default
old_field = Author._meta.get_field("height")
new_field = PositiveIntegerField(default=42)
@@ -962,10 +1077,10 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
columns = self.column_classes(Author)
- self.assertFalse(columns['height'][1][6])
+ self.assertFalse(columns["height"][1][6])
# Verify default value
- self.assertEqual(Author.objects.get(name='Not null author').height, 12)
- self.assertEqual(Author.objects.get(name='Null author').height, 42)
+ self.assertEqual(Author.objects.get(name="Not null author").height, 12)
+ self.assertEqual(Author.objects.get(name="Null author").height, 42)
def test_alter_charfield_to_null(self):
"""
@@ -976,28 +1091,28 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Change the CharField to null
- old_field = Author._meta.get_field('name')
+ old_field = Author._meta.get_field("name")
new_field = copy(old_field)
new_field.null = True
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
- @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific')
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_char_field_decrease_length(self):
# Create the table.
with connection.schema_editor() as editor:
editor.create_model(Author)
- Author.objects.create(name='x' * 255)
+ Author.objects.create(name="x" * 255)
# Change max_length of CharField.
- old_field = Author._meta.get_field('name')
+ old_field = Author._meta.get_field("name")
new_field = CharField(max_length=254)
- new_field.set_attributes_from_name('name')
+ new_field.set_attributes_from_name("name")
with connection.schema_editor() as editor:
- msg = 'value too long for type character varying(254)'
+ msg = "value too long for type character varying(254)"
with self.assertRaisesMessage(DataError, msg):
editor.alter_field(Author, old_field, new_field, strict=True)
- @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific')
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_with_custom_db_type(self):
from django.contrib.postgres.fields import ArrayField
@@ -1005,20 +1120,20 @@ class SchemaTests(TransactionTestCase):
field = ArrayField(CharField(max_length=255))
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Foo)
self.isolated_local_models = [Foo]
- old_field = Foo._meta.get_field('field')
+ old_field = Foo._meta.get_field("field")
new_field = ArrayField(CharField(max_length=16))
- new_field.set_attributes_from_name('field')
+ new_field.set_attributes_from_name("field")
new_field.model = Foo
with connection.schema_editor() as editor:
editor.alter_field(Foo, old_field, new_field, strict=True)
- @isolate_apps('schema')
- @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific')
+ @isolate_apps("schema")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_array_field_decrease_base_field_length(self):
from django.contrib.postgres.fields import ArrayField
@@ -1026,23 +1141,23 @@ class SchemaTests(TransactionTestCase):
field = ArrayField(CharField(max_length=16))
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(ArrayModel)
self.isolated_local_models = [ArrayModel]
- ArrayModel.objects.create(field=['x' * 16])
- old_field = ArrayModel._meta.get_field('field')
+ ArrayModel.objects.create(field=["x" * 16])
+ old_field = ArrayModel._meta.get_field("field")
new_field = ArrayField(CharField(max_length=15))
- new_field.set_attributes_from_name('field')
+ new_field.set_attributes_from_name("field")
new_field.model = ArrayModel
with connection.schema_editor() as editor:
- msg = 'value too long for type character varying(15)'
+ msg = "value too long for type character varying(15)"
with self.assertRaisesMessage(DataError, msg):
editor.alter_field(ArrayModel, old_field, new_field, strict=True)
- @isolate_apps('schema')
- @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific')
+ @isolate_apps("schema")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_array_field_decrease_nested_base_field_length(self):
from django.contrib.postgres.fields import ArrayField
@@ -1050,18 +1165,18 @@ class SchemaTests(TransactionTestCase):
field = ArrayField(ArrayField(CharField(max_length=16)))
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(ArrayModel)
self.isolated_local_models = [ArrayModel]
- ArrayModel.objects.create(field=[['x' * 16]])
- old_field = ArrayModel._meta.get_field('field')
+ ArrayModel.objects.create(field=[["x" * 16]])
+ old_field = ArrayModel._meta.get_field("field")
new_field = ArrayField(ArrayField(CharField(max_length=15)))
- new_field.set_attributes_from_name('field')
+ new_field.set_attributes_from_name("field")
new_field.model = ArrayModel
with connection.schema_editor() as editor:
- msg = 'value too long for type character varying(15)'
+ msg = "value too long for type character varying(15)"
with self.assertRaisesMessage(DataError, msg):
editor.alter_field(ArrayModel, old_field, new_field, strict=True)
@@ -1074,7 +1189,7 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Note)
# Change the TextField to null
- old_field = Note._meta.get_field('info')
+ old_field = Note._meta.get_field("info")
new_field = copy(old_field)
new_field.null = True
with connection.schema_editor() as editor:
@@ -1090,17 +1205,19 @@ class SchemaTests(TransactionTestCase):
editor.create_model(AuthorWithDefaultHeight)
# Ensure the field is right to begin with
columns = self.column_classes(AuthorWithDefaultHeight)
- self.assertTrue(columns['height'][1][6])
+ self.assertTrue(columns["height"][1][6])
# Alter the height field to NOT NULL keeping the previous default
old_field = AuthorWithDefaultHeight._meta.get_field("height")
new_field = PositiveIntegerField(default=42)
new_field.set_attributes_from_name("height")
with connection.schema_editor() as editor:
- editor.alter_field(AuthorWithDefaultHeight, old_field, new_field, strict=True)
+ editor.alter_field(
+ AuthorWithDefaultHeight, old_field, new_field, strict=True
+ )
columns = self.column_classes(AuthorWithDefaultHeight)
- self.assertFalse(columns['height'][1][6])
+ self.assertFalse(columns["height"][1][6])
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_alter_fk(self):
"""
Tests altering of FKs
@@ -1111,8 +1228,11 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Book)
# Ensure the field is right to begin with
columns = self.column_classes(Book)
- self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField'])
- self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
+ self.assertEqual(
+ columns["author_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
+ self.assertForeignKeyExists(Book, "author_id", "schema_author")
# Alter the FK
old_field = Book._meta.get_field("author")
new_field = ForeignKey(Author, CASCADE, editable=False)
@@ -1120,21 +1240,25 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(Book, old_field, new_field, strict=True)
columns = self.column_classes(Book)
- self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField'])
- self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
+ self.assertEqual(
+ columns["author_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
+ self.assertForeignKeyExists(Book, "author_id", "schema_author")
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_alter_to_fk(self):
"""
#24447 - Tests adding a FK constraint for an existing column
"""
+
class LocalBook(Model):
author = IntegerField()
title = CharField(max_length=100, db_index=True)
pub_date = DateTimeField()
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
self.local_models = [LocalBook]
@@ -1146,16 +1270,18 @@ class SchemaTests(TransactionTestCase):
# Ensure no FK constraint exists
constraints = self.get_constraints(LocalBook._meta.db_table)
for details in constraints.values():
- if details['foreign_key']:
- self.fail('Found an unexpected FK constraint to %s' % details['columns'])
+ if details["foreign_key"]:
+ self.fail(
+ "Found an unexpected FK constraint to %s" % details["columns"]
+ )
old_field = LocalBook._meta.get_field("author")
new_field = ForeignKey(Author, CASCADE)
new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.alter_field(LocalBook, old_field, new_field, strict=True)
- self.assertForeignKeyExists(LocalBook, 'author_id', 'schema_author')
+ self.assertForeignKeyExists(LocalBook, "author_id", "schema_author")
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_alter_o2o_to_fk(self):
"""
#24163 - Tests altering of OneToOneField to ForeignKey
@@ -1166,14 +1292,21 @@ class SchemaTests(TransactionTestCase):
editor.create_model(BookWithO2O)
# Ensure the field is right to begin with
columns = self.column_classes(BookWithO2O)
- self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField'])
+ self.assertEqual(
+ columns["author_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
# Ensure the field is unique
author = Author.objects.create(name="Joe")
- BookWithO2O.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
+ BookWithO2O.objects.create(
+ author=author, title="Django 1", pub_date=datetime.datetime.now()
+ )
with self.assertRaises(IntegrityError):
- BookWithO2O.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
+ BookWithO2O.objects.create(
+ author=author, title="Django 2", pub_date=datetime.datetime.now()
+ )
BookWithO2O.objects.all().delete()
- self.assertForeignKeyExists(BookWithO2O, 'author_id', 'schema_author')
+ self.assertForeignKeyExists(BookWithO2O, "author_id", "schema_author")
# Alter the OneToOneField to ForeignKey
old_field = BookWithO2O._meta.get_field("author")
new_field = ForeignKey(Author, CASCADE)
@@ -1181,13 +1314,20 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(BookWithO2O, old_field, new_field, strict=True)
columns = self.column_classes(Book)
- self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField'])
+ self.assertEqual(
+ columns["author_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
# Ensure the field is not unique anymore
- Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
- Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
- self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
+ Book.objects.create(
+ author=author, title="Django 1", pub_date=datetime.datetime.now()
+ )
+ Book.objects.create(
+ author=author, title="Django 2", pub_date=datetime.datetime.now()
+ )
+ self.assertForeignKeyExists(Book, "author_id", "schema_author")
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_alter_fk_to_o2o(self):
"""
#24163 - Tests altering of ForeignKey to OneToOneField
@@ -1198,13 +1338,20 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Book)
# Ensure the field is right to begin with
columns = self.column_classes(Book)
- self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField'])
+ self.assertEqual(
+ columns["author_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
# Ensure the field is not unique
author = Author.objects.create(name="Joe")
- Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
- Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
+ Book.objects.create(
+ author=author, title="Django 1", pub_date=datetime.datetime.now()
+ )
+ Book.objects.create(
+ author=author, title="Django 2", pub_date=datetime.datetime.now()
+ )
Book.objects.all().delete()
- self.assertForeignKeyExists(Book, 'author_id', 'schema_author')
+ self.assertForeignKeyExists(Book, "author_id", "schema_author")
# Alter the ForeignKey to OneToOneField
old_field = Book._meta.get_field("author")
new_field = OneToOneField(Author, CASCADE)
@@ -1212,12 +1359,19 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(Book, old_field, new_field, strict=True)
columns = self.column_classes(BookWithO2O)
- self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField'])
+ self.assertEqual(
+ columns["author_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
# Ensure the field is unique now
- BookWithO2O.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now())
+ BookWithO2O.objects.create(
+ author=author, title="Django 1", pub_date=datetime.datetime.now()
+ )
with self.assertRaises(IntegrityError):
- BookWithO2O.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now())
- self.assertForeignKeyExists(BookWithO2O, 'author_id', 'schema_author')
+ BookWithO2O.objects.create(
+ author=author, title="Django 2", pub_date=datetime.datetime.now()
+ )
+ self.assertForeignKeyExists(BookWithO2O, "author_id", "schema_author")
def test_alter_field_fk_to_o2o(self):
with connection.schema_editor() as editor:
@@ -1229,27 +1383,27 @@ class SchemaTests(TransactionTestCase):
# Check the index is right to begin with.
counts = self.get_constraints_count(
Book._meta.db_table,
- Book._meta.get_field('author').column,
+ Book._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
self.assertEqual(
counts,
- {'fks': expected_fks, 'uniques': 0, 'indexes': expected_indexes},
+ {"fks": expected_fks, "uniques": 0, "indexes": expected_indexes},
)
- old_field = Book._meta.get_field('author')
+ old_field = Book._meta.get_field("author")
new_field = OneToOneField(Author, CASCADE)
- new_field.set_attributes_from_name('author')
+ new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.alter_field(Book, old_field, new_field, strict=True)
counts = self.get_constraints_count(
Book._meta.db_table,
- Book._meta.get_field('author').column,
+ Book._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
# The index on ForeignKey is replaced with a unique constraint for OneToOneField.
- self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0})
+ self.assertEqual(counts, {"fks": expected_fks, "uniques": 1, "indexes": 0})
def test_alter_field_fk_keeps_index(self):
with connection.schema_editor() as editor:
@@ -1261,30 +1415,30 @@ class SchemaTests(TransactionTestCase):
# Check the index is right to begin with.
counts = self.get_constraints_count(
Book._meta.db_table,
- Book._meta.get_field('author').column,
+ Book._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
self.assertEqual(
counts,
- {'fks': expected_fks, 'uniques': 0, 'indexes': expected_indexes},
+ {"fks": expected_fks, "uniques": 0, "indexes": expected_indexes},
)
- old_field = Book._meta.get_field('author')
+ old_field = Book._meta.get_field("author")
# on_delete changed from CASCADE.
new_field = ForeignKey(Author, PROTECT)
- new_field.set_attributes_from_name('author')
+ new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.alter_field(Book, old_field, new_field, strict=True)
counts = self.get_constraints_count(
Book._meta.db_table,
- Book._meta.get_field('author').column,
+ Book._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
# The index remains.
self.assertEqual(
counts,
- {'fks': expected_fks, 'uniques': 0, 'indexes': expected_indexes},
+ {"fks": expected_fks, "uniques": 0, "indexes": expected_indexes},
)
def test_alter_field_o2o_to_fk(self):
@@ -1296,24 +1450,24 @@ class SchemaTests(TransactionTestCase):
# Check the unique constraint is right to begin with.
counts = self.get_constraints_count(
BookWithO2O._meta.db_table,
- BookWithO2O._meta.get_field('author').column,
+ BookWithO2O._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
- self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0})
+ self.assertEqual(counts, {"fks": expected_fks, "uniques": 1, "indexes": 0})
- old_field = BookWithO2O._meta.get_field('author')
+ old_field = BookWithO2O._meta.get_field("author")
new_field = ForeignKey(Author, CASCADE)
- new_field.set_attributes_from_name('author')
+ new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.alter_field(BookWithO2O, old_field, new_field, strict=True)
counts = self.get_constraints_count(
BookWithO2O._meta.db_table,
- BookWithO2O._meta.get_field('author').column,
+ BookWithO2O._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
# The unique constraint on OneToOneField is replaced with an index for ForeignKey.
- self.assertEqual(counts, {'fks': expected_fks, 'uniques': 0, 'indexes': 1})
+ self.assertEqual(counts, {"fks": expected_fks, "uniques": 0, "indexes": 1})
def test_alter_field_o2o_keeps_unique(self):
with connection.schema_editor() as editor:
@@ -1324,27 +1478,27 @@ class SchemaTests(TransactionTestCase):
# Check the unique constraint is right to begin with.
counts = self.get_constraints_count(
BookWithO2O._meta.db_table,
- BookWithO2O._meta.get_field('author').column,
+ BookWithO2O._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
- self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0})
+ self.assertEqual(counts, {"fks": expected_fks, "uniques": 1, "indexes": 0})
- old_field = BookWithO2O._meta.get_field('author')
+ old_field = BookWithO2O._meta.get_field("author")
# on_delete changed from CASCADE.
new_field = OneToOneField(Author, PROTECT)
- new_field.set_attributes_from_name('author')
+ new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.alter_field(BookWithO2O, old_field, new_field, strict=True)
counts = self.get_constraints_count(
BookWithO2O._meta.db_table,
- BookWithO2O._meta.get_field('author').column,
+ BookWithO2O._meta.get_field("author").column,
(Author._meta.db_table, Author._meta.pk.column),
)
# The unique constraint remains.
- self.assertEqual(counts, {'fks': expected_fks, 'uniques': 1, 'indexes': 0})
+ self.assertEqual(counts, {"fks": expected_fks, "uniques": 1, "indexes": 0})
- @skipUnlessDBFeature('ignores_table_name_case')
+ @skipUnlessDBFeature("ignores_table_name_case")
def test_alter_db_table_case(self):
# Create the table
with connection.schema_editor() as editor:
@@ -1370,8 +1524,8 @@ class SchemaTests(TransactionTestCase):
editor.alter_field(Author, old_field, new_field, strict=True)
# This will fail if DROP DEFAULT is inadvertently executed on this
# field which drops the id sequence, at least on PostgreSQL.
- Author.objects.create(name='Foo')
- Author.objects.create(name='Bar')
+ Author.objects.create(name="Foo")
+ Author.objects.create(name="Bar")
def test_alter_autofield_pk_to_bigautofield_pk_sequence_owner(self):
"""
@@ -1380,20 +1534,22 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(Author)
- old_field = Author._meta.get_field('id')
+ old_field = Author._meta.get_field("id")
new_field = BigAutoField(primary_key=True)
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
new_field.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
- Author.objects.create(name='Foo', pk=1)
+ Author.objects.create(name="Foo", pk=1)
with connection.cursor() as cursor:
- sequence_reset_sqls = connection.ops.sequence_reset_sql(no_style(), [Author])
+ sequence_reset_sqls = connection.ops.sequence_reset_sql(
+ no_style(), [Author]
+ )
if sequence_reset_sqls:
cursor.execute(sequence_reset_sqls[0])
# Fail on PostgreSQL if sequence is missing an owner.
- self.assertIsNotNone(Author.objects.create(name='Bar'))
+ self.assertIsNotNone(Author.objects.create(name="Bar"))
def test_alter_autofield_pk_to_smallautofield_pk_sequence_owner(self):
"""
@@ -1402,20 +1558,22 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(Author)
- old_field = Author._meta.get_field('id')
+ old_field = Author._meta.get_field("id")
new_field = SmallAutoField(primary_key=True)
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
new_field.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
- Author.objects.create(name='Foo', pk=1)
+ Author.objects.create(name="Foo", pk=1)
with connection.cursor() as cursor:
- sequence_reset_sqls = connection.ops.sequence_reset_sql(no_style(), [Author])
+ sequence_reset_sqls = connection.ops.sequence_reset_sql(
+ no_style(), [Author]
+ )
if sequence_reset_sqls:
cursor.execute(sequence_reset_sqls[0])
# Fail on PostgreSQL if sequence is missing an owner.
- self.assertIsNotNone(Author.objects.create(name='Bar'))
+ self.assertIsNotNone(Author.objects.create(name="Bar"))
def test_alter_int_pk_to_autofield_pk(self):
"""
@@ -1425,10 +1583,10 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(IntegerPK)
- old_field = IntegerPK._meta.get_field('i')
+ old_field = IntegerPK._meta.get_field("i")
new_field = AutoField(primary_key=True)
new_field.model = IntegerPK
- new_field.set_attributes_from_name('i')
+ new_field.set_attributes_from_name("i")
with connection.schema_editor() as editor:
editor.alter_field(IntegerPK, old_field, new_field, strict=True)
@@ -1439,7 +1597,7 @@ class SchemaTests(TransactionTestCase):
j = IntegerField(unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
db_table = IntegerPK._meta.db_table
@@ -1455,10 +1613,10 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(IntegerPK)
- old_field = IntegerPK._meta.get_field('i')
+ old_field = IntegerPK._meta.get_field("i")
new_field = BigAutoField(primary_key=True)
new_field.model = IntegerPK
- new_field.set_attributes_from_name('i')
+ new_field.set_attributes_from_name("i")
with connection.schema_editor() as editor:
editor.alter_field(IntegerPK, old_field, new_field, strict=True)
@@ -1469,7 +1627,7 @@ class SchemaTests(TransactionTestCase):
j = IntegerField(unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
db_table = IntegerPK._meta.db_table
@@ -1477,25 +1635,26 @@ class SchemaTests(TransactionTestCase):
obj = IntegerPKToBigAutoField.objects.create(j=1)
self.assertIsNotNone(obj.i)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_alter_smallint_pk_to_smallautofield_pk(self):
"""
Should be able to rename an SmallIntegerField(primary_key=True) to
SmallAutoField(primary_key=True).
"""
+
class SmallIntegerPK(Model):
i = SmallIntegerField(primary_key=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(SmallIntegerPK)
self.isolated_local_models = [SmallIntegerPK]
- old_field = SmallIntegerPK._meta.get_field('i')
+ old_field = SmallIntegerPK._meta.get_field("i")
new_field = SmallAutoField(primary_key=True)
new_field.model = SmallIntegerPK
- new_field.set_attributes_from_name('i')
+ new_field.set_attributes_from_name("i")
with connection.schema_editor() as editor:
editor.alter_field(SmallIntegerPK, old_field, new_field, strict=True)
@@ -1507,15 +1666,15 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(IntegerPK)
# Delete the old PK
- old_field = IntegerPK._meta.get_field('i')
+ old_field = IntegerPK._meta.get_field("i")
new_field = IntegerField(unique=True)
new_field.model = IntegerPK
- new_field.set_attributes_from_name('i')
+ new_field.set_attributes_from_name("i")
with connection.schema_editor() as editor:
editor.alter_field(IntegerPK, old_field, new_field, strict=True)
# The primary key constraint is gone. Result depends on database:
# 'id' for SQLite, None for others (must not be 'i').
- self.assertIn(self.get_primary_key(IntegerPK._meta.db_table), ('id', None))
+ self.assertIn(self.get_primary_key(IntegerPK._meta.db_table), ("id", None))
# Set up a model class as it currently stands. The original IntegerPK
# class is now out of date and some backends make use of the whole
@@ -1526,15 +1685,15 @@ class SchemaTests(TransactionTestCase):
j = IntegerField(unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
- db_table = 'INTEGERPK'
+ db_table = "INTEGERPK"
# model requires a new PK
- old_field = Transitional._meta.get_field('j')
+ old_field = Transitional._meta.get_field("j")
new_field = IntegerField(primary_key=True)
new_field.model = Transitional
- new_field.set_attributes_from_name('j')
+ new_field.set_attributes_from_name("j")
with connection.schema_editor() as editor:
editor.alter_field(Transitional, old_field, new_field, strict=True)
@@ -1545,9 +1704,9 @@ class SchemaTests(TransactionTestCase):
j = IntegerField(primary_key=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
- db_table = 'INTEGERPK'
+ db_table = "INTEGERPK"
# Ensure unique constraint works.
IntegerUnique.objects.create(i=1, j=1)
@@ -1563,7 +1722,10 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Author)
# Ensure the field is right to begin with
columns = self.column_classes(Author)
- self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField'])
+ self.assertEqual(
+ columns["name"][0],
+ connection.features.introspected_field_types["CharField"],
+ )
self.assertNotIn("display_name", columns)
# Alter the name field's name
old_field = Author._meta.get_field("name")
@@ -1572,34 +1734,39 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
columns = self.column_classes(Author)
- self.assertEqual(columns['display_name'][0], connection.features.introspected_field_types['CharField'])
+ self.assertEqual(
+ columns["display_name"][0],
+ connection.features.introspected_field_types["CharField"],
+ )
self.assertNotIn("name", columns)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_rename_referenced_field(self):
class Author(Model):
name = CharField(max_length=255, unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class Book(Model):
- author = ForeignKey(Author, CASCADE, to_field='name')
+ author = ForeignKey(Author, CASCADE, to_field="name")
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(Book)
new_field = CharField(max_length=255, unique=True)
- new_field.set_attributes_from_name('renamed')
- with connection.schema_editor(atomic=connection.features.supports_atomic_references_rename) as editor:
- editor.alter_field(Author, Author._meta.get_field('name'), new_field)
+ new_field.set_attributes_from_name("renamed")
+ with connection.schema_editor(
+ atomic=connection.features.supports_atomic_references_rename
+ ) as editor:
+ editor.alter_field(Author, Author._meta.get_field("name"), new_field)
# Ensure the foreign key reference was updated.
- self.assertForeignKeyExists(Book, 'author_id', 'schema_author', 'renamed')
+ self.assertForeignKeyExists(Book, "author_id", "schema_author", "renamed")
- @skipIfDBFeature('interprets_empty_strings_as_nulls')
+ @skipIfDBFeature("interprets_empty_strings_as_nulls")
def test_rename_keep_null_status(self):
"""
Renaming a field shouldn't affect the not null status.
@@ -1614,7 +1781,7 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.alter_field(Note, old_field, new_field, strict=True)
columns = self.column_classes(Note)
- self.assertEqual(columns['detail_info'][0], "TextField")
+ self.assertEqual(columns["detail_info"][0], "TextField")
self.assertNotIn("info", columns)
with self.assertRaises(IntegrityError):
NoteRename.objects.create(detail_info=None)
@@ -1623,6 +1790,7 @@ class SchemaTests(TransactionTestCase):
"""
Tests M2M fields on models during creation
"""
+
class LocalBookWithM2M(Model):
author = ForeignKey(Author, CASCADE)
title = CharField(max_length=100, db_index=True)
@@ -1630,8 +1798,9 @@ class SchemaTests(TransactionTestCase):
tags = M2MFieldClass("TagM2MTest", related_name="books")
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
+
self.local_models = [LocalBookWithM2M]
# Create the tables
with connection.schema_editor() as editor:
@@ -1639,8 +1808,13 @@ class SchemaTests(TransactionTestCase):
editor.create_model(TagM2MTest)
editor.create_model(LocalBookWithM2M)
# Ensure there is now an m2m table there
- columns = self.column_classes(LocalBookWithM2M._meta.get_field("tags").remote_field.through)
- self.assertEqual(columns['tagm2mtest_id'][0], connection.features.introspected_field_types['IntegerField'])
+ columns = self.column_classes(
+ LocalBookWithM2M._meta.get_field("tags").remote_field.through
+ )
+ self.assertEqual(
+ columns["tagm2mtest_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
def test_m2m_create(self):
self._test_m2m_create(ManyToManyField)
@@ -1655,19 +1829,22 @@ class SchemaTests(TransactionTestCase):
"""
Tests M2M fields on models during creation with through models
"""
+
class LocalTagThrough(Model):
book = ForeignKey("schema.LocalBookWithM2MThrough", CASCADE)
tag = ForeignKey("schema.TagM2MTest", CASCADE)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
class LocalBookWithM2MThrough(Model):
- tags = M2MFieldClass("TagM2MTest", related_name="books", through=LocalTagThrough)
+ tags = M2MFieldClass(
+ "TagM2MTest", related_name="books", through=LocalTagThrough
+ )
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
self.local_models = [LocalTagThrough, LocalBookWithM2MThrough]
@@ -1679,8 +1856,14 @@ class SchemaTests(TransactionTestCase):
editor.create_model(LocalBookWithM2MThrough)
# Ensure there is now an m2m table there
columns = self.column_classes(LocalTagThrough)
- self.assertEqual(columns['book_id'][0], connection.features.introspected_field_types['IntegerField'])
- self.assertEqual(columns['tag_id'][0], connection.features.introspected_field_types['IntegerField'])
+ self.assertEqual(
+ columns["book_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
+ self.assertEqual(
+ columns["tag_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
def test_m2m_create_through(self):
self._test_m2m_create_through(ManyToManyField)
@@ -1695,11 +1878,12 @@ class SchemaTests(TransactionTestCase):
"""
Tests adding/removing M2M fields on models
"""
+
class LocalAuthorWithM2M(Model):
name = CharField(max_length=255)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
self.local_models = [LocalAuthorWithM2M]
@@ -1719,7 +1903,10 @@ class SchemaTests(TransactionTestCase):
editor.add_field(LocalAuthorWithM2M, new_field)
# Ensure there is now an m2m table there
columns = self.column_classes(new_field.remote_field.through)
- self.assertEqual(columns['tagm2mtest_id'][0], connection.features.introspected_field_types['IntegerField'])
+ self.assertEqual(
+ columns["tagm2mtest_id"][0],
+ connection.features.introspected_field_types["IntegerField"],
+ )
# "Alter" the field. This should not rename the DB table to itself.
with connection.schema_editor() as editor:
@@ -1736,7 +1923,9 @@ class SchemaTests(TransactionTestCase):
# we've removed the tags field.
opts = LocalAuthorWithM2M._meta
opts.local_many_to_many.remove(new_field)
- del new_apps.all_models['schema'][new_field.remote_field.through._meta.model_name]
+ del new_apps.all_models["schema"][
+ new_field.remote_field.through._meta.model_name
+ ]
opts._expire_cache()
def test_m2m(self):
@@ -1752,20 +1941,23 @@ class SchemaTests(TransactionTestCase):
"""
Tests altering M2Ms with explicit through models (should no-op)
"""
+
class LocalAuthorTag(Model):
author = ForeignKey("schema.LocalAuthorWithM2MThrough", CASCADE)
tag = ForeignKey("schema.TagM2MTest", CASCADE)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
class LocalAuthorWithM2MThrough(Model):
name = CharField(max_length=255)
- tags = M2MFieldClass("schema.TagM2MTest", related_name="authors", through=LocalAuthorTag)
+ tags = M2MFieldClass(
+ "schema.TagM2MTest", related_name="authors", through=LocalAuthorTag
+ )
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
self.local_models = [LocalAuthorTag, LocalAuthorWithM2MThrough]
@@ -1779,10 +1971,14 @@ class SchemaTests(TransactionTestCase):
self.assertEqual(len(self.column_classes(LocalAuthorTag)), 3)
# "Alter" the field's blankness. This should not actually do anything.
old_field = LocalAuthorWithM2MThrough._meta.get_field("tags")
- new_field = M2MFieldClass("schema.TagM2MTest", related_name="authors", through=LocalAuthorTag)
+ new_field = M2MFieldClass(
+ "schema.TagM2MTest", related_name="authors", through=LocalAuthorTag
+ )
new_field.contribute_to_class(LocalAuthorWithM2MThrough, "tags")
with connection.schema_editor() as editor:
- editor.alter_field(LocalAuthorWithM2MThrough, old_field, new_field, strict=True)
+ editor.alter_field(
+ LocalAuthorWithM2MThrough, old_field, new_field, strict=True
+ )
# Ensure the m2m table is still there
self.assertEqual(len(self.column_classes(LocalAuthorTag)), 3)
@@ -1799,6 +1995,7 @@ class SchemaTests(TransactionTestCase):
"""
Tests repointing M2M fields
"""
+
class LocalBookWithM2M(Model):
author = ForeignKey(Author, CASCADE)
title = CharField(max_length=100, db_index=True)
@@ -1806,8 +2003,9 @@ class SchemaTests(TransactionTestCase):
tags = M2MFieldClass("TagM2MTest", related_name="books")
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
+
self.local_models = [LocalBookWithM2M]
# Create the tables
with connection.schema_editor() as editor:
@@ -1819,8 +2017,8 @@ class SchemaTests(TransactionTestCase):
if connection.features.supports_foreign_keys:
self.assertForeignKeyExists(
LocalBookWithM2M._meta.get_field("tags").remote_field.through,
- 'tagm2mtest_id',
- 'schema_tagm2mtest',
+ "tagm2mtest_id",
+ "schema_tagm2mtest",
)
# Repoint the M2M
old_field = LocalBookWithM2M._meta.get_field("tags")
@@ -1830,14 +2028,18 @@ class SchemaTests(TransactionTestCase):
editor.alter_field(LocalBookWithM2M, old_field, new_field, strict=True)
# Ensure old M2M is gone
with self.assertRaises(DatabaseError):
- self.column_classes(LocalBookWithM2M._meta.get_field("tags").remote_field.through)
+ self.column_classes(
+ LocalBookWithM2M._meta.get_field("tags").remote_field.through
+ )
# This model looks like the new model and is used for teardown.
opts = LocalBookWithM2M._meta
opts.local_many_to_many.remove(old_field)
# Ensure the new M2M exists and points to UniqueTest
if connection.features.supports_foreign_keys:
- self.assertForeignKeyExists(new_field.remote_field.through, 'uniquetest_id', 'schema_uniquetest')
+ self.assertForeignKeyExists(
+ new_field.remote_field.through, "uniquetest_id", "schema_uniquetest"
+ )
def test_m2m_repoint(self):
self._test_m2m_repoint(ManyToManyField)
@@ -1848,19 +2050,19 @@ class SchemaTests(TransactionTestCase):
def test_m2m_repoint_inherited(self):
self._test_m2m_repoint(InheritedManyToManyField)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_m2m_rename_field_in_target_model(self):
class LocalTagM2MTest(Model):
title = CharField(max_length=255)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class LocalM2M(Model):
tags = ManyToManyField(LocalTagM2MTest)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
# Create the tables.
with connection.schema_editor() as editor:
@@ -1870,9 +2072,9 @@ class SchemaTests(TransactionTestCase):
# Ensure the m2m table is there.
self.assertEqual(len(self.column_classes(LocalM2M)), 1)
# Alter a field in LocalTagM2MTest.
- old_field = LocalTagM2MTest._meta.get_field('title')
+ old_field = LocalTagM2MTest._meta.get_field("title")
new_field = CharField(max_length=254)
- new_field.contribute_to_class(LocalTagM2MTest, 'title1')
+ new_field.contribute_to_class(LocalTagM2MTest, "title1")
# @isolate_apps() and inner models are needed to have the model
# relations populated, otherwise this doesn't act as a regression test.
self.assertEqual(len(new_field.model._meta.related_objects), 1)
@@ -1881,7 +2083,9 @@ class SchemaTests(TransactionTestCase):
# Ensure the m2m table is still there.
self.assertEqual(len(self.column_classes(LocalM2M)), 1)
- @skipUnlessDBFeature('supports_column_check_constraints', 'can_introspect_check_constraints')
+ @skipUnlessDBFeature(
+ "supports_column_check_constraints", "can_introspect_check_constraints"
+ )
def test_check_constraints(self):
"""
Tests creating/deleting CHECK constraints
@@ -1891,7 +2095,10 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Author)
# Ensure the constraint exists
constraints = self.get_constraints(Author._meta.db_table)
- if not any(details['columns'] == ['height'] and details['check'] for details in constraints.values()):
+ if not any(
+ details["columns"] == ["height"] and details["check"]
+ for details in constraints.values()
+ ):
self.fail("No check constraint for height found")
# Alter the column to remove it
old_field = Author._meta.get_field("height")
@@ -1901,29 +2108,34 @@ class SchemaTests(TransactionTestCase):
editor.alter_field(Author, old_field, new_field, strict=True)
constraints = self.get_constraints(Author._meta.db_table)
for details in constraints.values():
- if details['columns'] == ["height"] and details['check']:
+ if details["columns"] == ["height"] and details["check"]:
self.fail("Check constraint for height found")
# Alter the column to re-add it
new_field2 = Author._meta.get_field("height")
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, new_field2, strict=True)
constraints = self.get_constraints(Author._meta.db_table)
- if not any(details['columns'] == ['height'] and details['check'] for details in constraints.values()):
+ if not any(
+ details["columns"] == ["height"] and details["check"]
+ for details in constraints.values()
+ ):
self.fail("No check constraint for height found")
- @skipUnlessDBFeature('supports_column_check_constraints', 'can_introspect_check_constraints')
- @isolate_apps('schema')
+ @skipUnlessDBFeature(
+ "supports_column_check_constraints", "can_introspect_check_constraints"
+ )
+ @isolate_apps("schema")
def test_check_constraint_timedelta_param(self):
class DurationModel(Model):
duration = DurationField()
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(DurationModel)
self.isolated_local_models = [DurationModel]
- constraint_name = 'duration_gte_5_minutes'
+ constraint_name = "duration_gte_5_minutes"
constraint = CheckConstraint(
check=Q(duration__gt=datetime.timedelta(minutes=5)),
name=constraint_name,
@@ -1937,12 +2149,16 @@ class SchemaTests(TransactionTestCase):
DurationModel.objects.create(duration=datetime.timedelta(minutes=4))
DurationModel.objects.create(duration=datetime.timedelta(minutes=10))
- @skipUnlessDBFeature('supports_column_check_constraints', 'can_introspect_check_constraints')
+ @skipUnlessDBFeature(
+ "supports_column_check_constraints", "can_introspect_check_constraints"
+ )
def test_remove_field_check_does_not_remove_meta_constraints(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Add the custom check constraint
- constraint = CheckConstraint(check=Q(height__gte=0), name='author_height_gte_0_check')
+ constraint = CheckConstraint(
+ check=Q(height__gte=0), name="author_height_gte_0_check"
+ )
custom_constraint_name = constraint.name
Author._meta.constraints = [constraint]
with connection.schema_editor() as editor:
@@ -1951,32 +2167,41 @@ class SchemaTests(TransactionTestCase):
constraints = self.get_constraints(Author._meta.db_table)
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['height'] and details['check'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["height"]
+ and details["check"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 1)
# Alter the column to remove field check
- old_field = Author._meta.get_field('height')
+ old_field = Author._meta.get_field("height")
new_field = IntegerField(null=True, blank=True)
- new_field.set_attributes_from_name('height')
+ new_field.set_attributes_from_name("height")
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
constraints = self.get_constraints(Author._meta.db_table)
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['height'] and details['check'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["height"]
+ and details["check"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 0)
# Alter the column to re-add field check
- new_field2 = Author._meta.get_field('height')
+ new_field2 = Author._meta.get_field("height")
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, new_field2, strict=True)
constraints = self.get_constraints(Author._meta.db_table)
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['height'] and details['check'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["height"]
+ and details["check"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 1)
# Drop the check constraint
@@ -2032,15 +2257,15 @@ class SchemaTests(TransactionTestCase):
try:
with connection.schema_editor() as editor:
editor.create_model(TagUniqueRename)
- editor.alter_db_table(TagUniqueRename, old_table_name, 'unique-table')
- TagUniqueRename._meta.db_table = 'unique-table'
+ editor.alter_db_table(TagUniqueRename, old_table_name, "unique-table")
+ TagUniqueRename._meta.db_table = "unique-table"
# This fails if the unique index name isn't quoted.
- editor.alter_unique_together(TagUniqueRename, [], (('title', 'slug2'),))
+ editor.alter_unique_together(TagUniqueRename, [], (("title", "slug2"),))
finally:
TagUniqueRename._meta.db_table = old_table_name
- @isolate_apps('schema')
- @skipUnlessDBFeature('supports_foreign_keys')
+ @isolate_apps("schema")
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_unique_no_unnecessary_fk_drops(self):
"""
If AlterField isn't selective about dropping foreign key constraints
@@ -2048,72 +2273,74 @@ class SchemaTests(TransactionTestCase):
incorrectly drops and recreates the Book.author foreign key even though
it doesn't restrict the field being changed (#29193).
"""
+
class Author(Model):
name = CharField(max_length=254, unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class Book(Model):
author = ForeignKey(Author, CASCADE)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(Book)
new_field = CharField(max_length=255, unique=True)
new_field.model = Author
- new_field.set_attributes_from_name('name')
- with self.assertLogs('django.db.backends.schema', 'DEBUG') as cm:
+ new_field.set_attributes_from_name("name")
+ with self.assertLogs("django.db.backends.schema", "DEBUG") as cm:
with connection.schema_editor() as editor:
- editor.alter_field(Author, Author._meta.get_field('name'), new_field)
+ editor.alter_field(Author, Author._meta.get_field("name"), new_field)
# One SQL statement is executed to alter the field.
self.assertEqual(len(cm.records), 1)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_unique_and_reverse_m2m(self):
"""
AlterField can modify a unique field when there's a reverse M2M
relation on the model.
"""
+
class Tag(Model):
title = CharField(max_length=255)
slug = SlugField(unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class Book(Model):
- tags = ManyToManyField(Tag, related_name='books')
+ tags = ManyToManyField(Tag, related_name="books")
class Meta:
- app_label = 'schema'
+ app_label = "schema"
- self.isolated_local_models = [Book._meta.get_field('tags').remote_field.through]
+ self.isolated_local_models = [Book._meta.get_field("tags").remote_field.through]
with connection.schema_editor() as editor:
editor.create_model(Tag)
editor.create_model(Book)
new_field = SlugField(max_length=75, unique=True)
new_field.model = Tag
- new_field.set_attributes_from_name('slug')
- with self.assertLogs('django.db.backends.schema', 'DEBUG') as cm:
+ new_field.set_attributes_from_name("slug")
+ with self.assertLogs("django.db.backends.schema", "DEBUG") as cm:
with connection.schema_editor() as editor:
- editor.alter_field(Tag, Tag._meta.get_field('slug'), new_field)
+ editor.alter_field(Tag, Tag._meta.get_field("slug"), new_field)
# One SQL statement is executed to alter the field.
self.assertEqual(len(cm.records), 1)
# Ensure that the field is still unique.
- Tag.objects.create(title='foo', slug='foo')
+ Tag.objects.create(title="foo", slug="foo")
with self.assertRaises(IntegrityError):
- Tag.objects.create(title='bar', slug='foo')
+ Tag.objects.create(title="bar", slug="foo")
- @skipUnlessDBFeature('allows_multiple_constraints_on_same_fields')
+ @skipUnlessDBFeature("allows_multiple_constraints_on_same_fields")
def test_remove_field_unique_does_not_remove_meta_constraints(self):
with connection.schema_editor() as editor:
editor.create_model(AuthorWithUniqueName)
# Add the custom unique constraint
- constraint = UniqueConstraint(fields=['name'], name='author_name_uniq')
+ constraint = UniqueConstraint(fields=["name"], name="author_name_uniq")
custom_constraint_name = constraint.name
AuthorWithUniqueName._meta.constraints = [constraint]
with connection.schema_editor() as editor:
@@ -2122,32 +2349,41 @@ class SchemaTests(TransactionTestCase):
constraints = self.get_constraints(AuthorWithUniqueName._meta.db_table)
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name'] and details['unique'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name"]
+ and details["unique"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 1)
# Alter the column to remove field uniqueness
- old_field = AuthorWithUniqueName._meta.get_field('name')
+ old_field = AuthorWithUniqueName._meta.get_field("name")
new_field = CharField(max_length=255)
- new_field.set_attributes_from_name('name')
+ new_field.set_attributes_from_name("name")
with connection.schema_editor() as editor:
editor.alter_field(AuthorWithUniqueName, old_field, new_field, strict=True)
constraints = self.get_constraints(AuthorWithUniqueName._meta.db_table)
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name'] and details['unique'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name"]
+ and details["unique"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 0)
# Alter the column to re-add field uniqueness
- new_field2 = AuthorWithUniqueName._meta.get_field('name')
+ new_field2 = AuthorWithUniqueName._meta.get_field("name")
with connection.schema_editor() as editor:
editor.alter_field(AuthorWithUniqueName, new_field, new_field2, strict=True)
constraints = self.get_constraints(AuthorWithUniqueName._meta.db_table)
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name'] and details['unique'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name"]
+ and details["unique"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 1)
# Drop the unique constraint
@@ -2171,7 +2407,9 @@ class SchemaTests(TransactionTestCase):
UniqueTest.objects.all().delete()
# Alter the model to its non-unique-together companion
with connection.schema_editor() as editor:
- editor.alter_unique_together(UniqueTest, UniqueTest._meta.unique_together, [])
+ editor.alter_unique_together(
+ UniqueTest, UniqueTest._meta.unique_together, []
+ )
# Ensure the fields are no longer unique
UniqueTest.objects.create(year=2012, slug="foo")
UniqueTest.objects.create(year=2012, slug="foo")
@@ -2180,7 +2418,9 @@ class SchemaTests(TransactionTestCase):
new_field2 = SlugField(unique=True)
new_field2.set_attributes_from_name("slug")
with connection.schema_editor() as editor:
- editor.alter_unique_together(UniqueTest, [], UniqueTest._meta.unique_together)
+ editor.alter_unique_together(
+ UniqueTest, [], UniqueTest._meta.unique_together
+ )
# Ensure the fields are unique again
UniqueTest.objects.create(year=2012, slug="foo")
with self.assertRaises(IntegrityError):
@@ -2200,10 +2440,10 @@ class SchemaTests(TransactionTestCase):
self.assertEqual(Book._meta.unique_together, ())
# Add the unique_together constraint
with connection.schema_editor() as editor:
- editor.alter_unique_together(Book, [], [['author', 'title']])
+ editor.alter_unique_together(Book, [], [["author", "title"]])
# Alter it back
with connection.schema_editor() as editor:
- editor.alter_unique_together(Book, [['author', 'title']], [])
+ editor.alter_unique_together(Book, [["author", "title"]], [])
def test_unique_together_with_fk_with_existing_index(self):
"""
@@ -2216,54 +2456,75 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Author)
editor.create_model(BookWithoutAuthor)
new_field = ForeignKey(Author, CASCADE)
- new_field.set_attributes_from_name('author')
+ new_field.set_attributes_from_name("author")
editor.add_field(BookWithoutAuthor, new_field)
# Ensure the fields aren't unique to begin with
self.assertEqual(Book._meta.unique_together, ())
# Add the unique_together constraint
with connection.schema_editor() as editor:
- editor.alter_unique_together(Book, [], [['author', 'title']])
+ editor.alter_unique_together(Book, [], [["author", "title"]])
# Alter it back
with connection.schema_editor() as editor:
- editor.alter_unique_together(Book, [['author', 'title']], [])
+ editor.alter_unique_together(Book, [["author", "title"]], [])
- @skipUnlessDBFeature('allows_multiple_constraints_on_same_fields')
+ @skipUnlessDBFeature("allows_multiple_constraints_on_same_fields")
def test_remove_unique_together_does_not_remove_meta_constraints(self):
with connection.schema_editor() as editor:
editor.create_model(AuthorWithUniqueNameAndBirthday)
# Add the custom unique constraint
- constraint = UniqueConstraint(fields=['name', 'birthday'], name='author_name_birthday_uniq')
+ constraint = UniqueConstraint(
+ fields=["name", "birthday"], name="author_name_birthday_uniq"
+ )
custom_constraint_name = constraint.name
AuthorWithUniqueNameAndBirthday._meta.constraints = [constraint]
with connection.schema_editor() as editor:
editor.add_constraint(AuthorWithUniqueNameAndBirthday, constraint)
# Ensure the constraints exist
- constraints = self.get_constraints(AuthorWithUniqueNameAndBirthday._meta.db_table)
+ constraints = self.get_constraints(
+ AuthorWithUniqueNameAndBirthday._meta.db_table
+ )
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name', 'birthday'] and details['unique'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name", "birthday"]
+ and details["unique"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 1)
# Remove unique together
unique_together = AuthorWithUniqueNameAndBirthday._meta.unique_together
with connection.schema_editor() as editor:
- editor.alter_unique_together(AuthorWithUniqueNameAndBirthday, unique_together, [])
- constraints = self.get_constraints(AuthorWithUniqueNameAndBirthday._meta.db_table)
+ editor.alter_unique_together(
+ AuthorWithUniqueNameAndBirthday, unique_together, []
+ )
+ constraints = self.get_constraints(
+ AuthorWithUniqueNameAndBirthday._meta.db_table
+ )
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name', 'birthday'] and details['unique'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name", "birthday"]
+ and details["unique"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 0)
# Re-add unique together
with connection.schema_editor() as editor:
- editor.alter_unique_together(AuthorWithUniqueNameAndBirthday, [], unique_together)
- constraints = self.get_constraints(AuthorWithUniqueNameAndBirthday._meta.db_table)
+ editor.alter_unique_together(
+ AuthorWithUniqueNameAndBirthday, [], unique_together
+ )
+ constraints = self.get_constraints(
+ AuthorWithUniqueNameAndBirthday._meta.db_table
+ )
self.assertIn(custom_constraint_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name', 'birthday'] and details['unique'] and name != custom_constraint_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name", "birthday"]
+ and details["unique"]
+ and name != custom_constraint_name
]
self.assertEqual(len(other_constraints), 1)
# Drop the unique constraint
@@ -2274,24 +2535,24 @@ class SchemaTests(TransactionTestCase):
def test_unique_constraint(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- constraint = UniqueConstraint(fields=['name'], name='name_uq')
+ constraint = UniqueConstraint(fields=["name"], name="name_uq")
# Add constraint.
with connection.schema_editor() as editor:
editor.add_constraint(Author, constraint)
sql = constraint.create_sql(Author, editor)
table = Author._meta.db_table
self.assertIs(sql.references_table(table), True)
- self.assertIs(sql.references_column(table, 'name'), True)
+ self.assertIs(sql.references_column(table, "name"), True)
# Remove constraint.
with connection.schema_editor() as editor:
editor.remove_constraint(Author, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_unique_constraint(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- constraint = UniqueConstraint(Upper('name').desc(), name='func_upper_uq')
+ constraint = UniqueConstraint(Upper("name").desc(), name="func_upper_uq")
# Add constraint.
with connection.schema_editor() as editor:
editor.add_constraint(Author, constraint)
@@ -2299,26 +2560,26 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
constraints = self.get_constraints(table)
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(table, constraint.name, ['DESC'])
+ self.assertIndexOrder(table, constraint.name, ["DESC"])
self.assertIn(constraint.name, constraints)
- self.assertIs(constraints[constraint.name]['unique'], True)
+ self.assertIs(constraints[constraint.name]["unique"], True)
# SQL contains a database function.
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIn('UPPER(%s)' % editor.quote_name('name'), str(sql))
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIn("UPPER(%s)" % editor.quote_name("name"), str(sql))
# Remove constraint.
with connection.schema_editor() as editor:
editor.remove_constraint(Author, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_composite_func_unique_constraint(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(BookWithSlug)
constraint = UniqueConstraint(
- Upper('title'),
- Lower('slug'),
- name='func_upper_lower_unq',
+ Upper("title"),
+ Lower("slug"),
+ name="func_upper_lower_unq",
)
# Add constraint.
with connection.schema_editor() as editor:
@@ -2327,28 +2588,28 @@ class SchemaTests(TransactionTestCase):
table = BookWithSlug._meta.db_table
constraints = self.get_constraints(table)
self.assertIn(constraint.name, constraints)
- self.assertIs(constraints[constraint.name]['unique'], True)
+ self.assertIs(constraints[constraint.name]["unique"], True)
# SQL contains database functions.
- self.assertIs(sql.references_column(table, 'title'), True)
- self.assertIs(sql.references_column(table, 'slug'), True)
+ self.assertIs(sql.references_column(table, "title"), True)
+ self.assertIs(sql.references_column(table, "slug"), True)
sql = str(sql)
- self.assertIn('UPPER(%s)' % editor.quote_name('title'), sql)
- self.assertIn('LOWER(%s)' % editor.quote_name('slug'), sql)
- self.assertLess(sql.index('UPPER'), sql.index('LOWER'))
+ self.assertIn("UPPER(%s)" % editor.quote_name("title"), sql)
+ self.assertIn("LOWER(%s)" % editor.quote_name("slug"), sql)
+ self.assertLess(sql.index("UPPER"), sql.index("LOWER"))
# Remove constraint.
with connection.schema_editor() as editor:
editor.remove_constraint(BookWithSlug, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_unique_constraint_field_and_expression(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
constraint = UniqueConstraint(
- F('height').desc(),
- 'uuid',
- Lower('name').asc(),
- name='func_f_lower_field_unq',
+ F("height").desc(),
+ "uuid",
+ Lower("name").asc(),
+ name="func_f_lower_field_unq",
)
# Add constraint.
with connection.schema_editor() as editor:
@@ -2356,28 +2617,28 @@ class SchemaTests(TransactionTestCase):
sql = constraint.create_sql(Author, editor)
table = Author._meta.db_table
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(table, constraint.name, ['DESC', 'ASC', 'ASC'])
+ self.assertIndexOrder(table, constraint.name, ["DESC", "ASC", "ASC"])
constraints = self.get_constraints(table)
- self.assertIs(constraints[constraint.name]['unique'], True)
- self.assertEqual(len(constraints[constraint.name]['columns']), 3)
- self.assertEqual(constraints[constraint.name]['columns'][1], 'uuid')
+ self.assertIs(constraints[constraint.name]["unique"], True)
+ self.assertEqual(len(constraints[constraint.name]["columns"]), 3)
+ self.assertEqual(constraints[constraint.name]["columns"][1], "uuid")
# SQL contains database functions and columns.
- self.assertIs(sql.references_column(table, 'height'), True)
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIs(sql.references_column(table, 'uuid'), True)
- self.assertIn('LOWER(%s)' % editor.quote_name('name'), str(sql))
+ self.assertIs(sql.references_column(table, "height"), True)
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIs(sql.references_column(table, "uuid"), True)
+ self.assertIn("LOWER(%s)" % editor.quote_name("name"), str(sql))
# Remove constraint.
with connection.schema_editor() as editor:
editor.remove_constraint(Author, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes', 'supports_partial_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes", "supports_partial_indexes")
def test_func_unique_constraint_partial(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
constraint = UniqueConstraint(
- Upper('name'),
- name='func_upper_cond_weight_uq',
+ Upper("name"),
+ name="func_upper_cond_weight_uq",
condition=Q(weight__isnull=False),
)
# Add constraint.
@@ -2387,11 +2648,11 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
constraints = self.get_constraints(table)
self.assertIn(constraint.name, constraints)
- self.assertIs(constraints[constraint.name]['unique'], True)
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIn('UPPER(%s)' % editor.quote_name('name'), str(sql))
+ self.assertIs(constraints[constraint.name]["unique"], True)
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIn("UPPER(%s)" % editor.quote_name("name"), str(sql))
self.assertIn(
- 'WHERE %s IS NOT NULL' % editor.quote_name('weight'),
+ "WHERE %s IS NOT NULL" % editor.quote_name("weight"),
str(sql),
)
# Remove constraint.
@@ -2399,14 +2660,14 @@ class SchemaTests(TransactionTestCase):
editor.remove_constraint(Author, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes', 'supports_covering_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes", "supports_covering_indexes")
def test_func_unique_constraint_covering(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
constraint = UniqueConstraint(
- Upper('name'),
- name='func_upper_covering_uq',
- include=['weight', 'height'],
+ Upper("name"),
+ name="func_upper_covering_uq",
+ include=["weight", "height"],
)
# Add constraint.
with connection.schema_editor() as editor:
@@ -2415,19 +2676,20 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
constraints = self.get_constraints(table)
self.assertIn(constraint.name, constraints)
- self.assertIs(constraints[constraint.name]['unique'], True)
+ self.assertIs(constraints[constraint.name]["unique"], True)
self.assertEqual(
- constraints[constraint.name]['columns'],
- [None, 'weight', 'height'],
+ constraints[constraint.name]["columns"],
+ [None, "weight", "height"],
)
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIs(sql.references_column(table, 'weight'), True)
- self.assertIs(sql.references_column(table, 'height'), True)
- self.assertIn('UPPER(%s)' % editor.quote_name('name'), str(sql))
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIs(sql.references_column(table, "weight"), True)
+ self.assertIs(sql.references_column(table, "height"), True)
+ self.assertIn("UPPER(%s)" % editor.quote_name("name"), str(sql))
self.assertIn(
- 'INCLUDE (%s, %s)' % (
- editor.quote_name('weight'),
- editor.quote_name('height'),
+ "INCLUDE (%s, %s)"
+ % (
+ editor.quote_name("weight"),
+ editor.quote_name("height"),
),
str(sql),
)
@@ -2436,15 +2698,15 @@ class SchemaTests(TransactionTestCase):
editor.remove_constraint(Author, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_unique_constraint_lookups(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
with register_lookup(CharField, Lower), register_lookup(IntegerField, Abs):
constraint = UniqueConstraint(
- F('name__lower'),
- F('weight__abs'),
- name='func_lower_abs_lookup_uq',
+ F("name__lower"),
+ F("weight__abs"),
+ name="func_lower_abs_lookup_uq",
)
# Add constraint.
with connection.schema_editor() as editor:
@@ -2453,29 +2715,27 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
constraints = self.get_constraints(table)
self.assertIn(constraint.name, constraints)
- self.assertIs(constraints[constraint.name]['unique'], True)
+ self.assertIs(constraints[constraint.name]["unique"], True)
# SQL contains columns.
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIs(sql.references_column(table, 'weight'), True)
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIs(sql.references_column(table, "weight"), True)
# Remove constraint.
with connection.schema_editor() as editor:
editor.remove_constraint(Author, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_unique_constraint_collate(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest(
- 'This backend does not support case-insensitive collations.'
- )
+ self.skipTest("This backend does not support case-insensitive collations.")
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(BookWithSlug)
constraint = UniqueConstraint(
- Collate(F('title'), collation=collation).desc(),
- Collate('slug', collation=collation),
- name='func_collate_uq',
+ Collate(F("title"), collation=collation).desc(),
+ Collate("slug", collation=collation),
+ name="func_collate_uq",
)
# Add constraint.
with connection.schema_editor() as editor:
@@ -2484,32 +2744,32 @@ class SchemaTests(TransactionTestCase):
table = BookWithSlug._meta.db_table
constraints = self.get_constraints(table)
self.assertIn(constraint.name, constraints)
- self.assertIs(constraints[constraint.name]['unique'], True)
+ self.assertIs(constraints[constraint.name]["unique"], True)
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(table, constraint.name, ['DESC', 'ASC'])
+ self.assertIndexOrder(table, constraint.name, ["DESC", "ASC"])
# SQL contains columns and a collation.
- self.assertIs(sql.references_column(table, 'title'), True)
- self.assertIs(sql.references_column(table, 'slug'), True)
- self.assertIn('COLLATE %s' % editor.quote_name(collation), str(sql))
+ self.assertIs(sql.references_column(table, "title"), True)
+ self.assertIs(sql.references_column(table, "slug"), True)
+ self.assertIn("COLLATE %s" % editor.quote_name(collation), str(sql))
# Remove constraint.
with connection.schema_editor() as editor:
editor.remove_constraint(BookWithSlug, constraint)
self.assertNotIn(constraint.name, self.get_constraints(table))
- @skipIfDBFeature('supports_expression_indexes')
+ @skipIfDBFeature("supports_expression_indexes")
def test_func_unique_constraint_unsupported(self):
# UniqueConstraint is ignored on databases that don't support indexes on
# expressions.
with connection.schema_editor() as editor:
editor.create_model(Author)
- constraint = UniqueConstraint(F('name'), name='func_name_uq')
+ constraint = UniqueConstraint(F("name"), name="func_name_uq")
with connection.schema_editor() as editor, self.assertNumQueries(0):
self.assertIsNone(editor.add_constraint(Author, constraint))
self.assertIsNone(editor.remove_constraint(Author, constraint))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_unique_constraint_nonexistent_field(self):
- constraint = UniqueConstraint(Lower('nonexistent'), name='func_nonexistent_uq')
+ constraint = UniqueConstraint(Lower("nonexistent"), name="func_nonexistent_uq")
msg = (
"Cannot resolve keyword 'nonexistent' into field. Choices are: "
"height, id, name, uuid, weight"
@@ -2518,11 +2778,11 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.add_constraint(Author, constraint)
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_unique_constraint_nondeterministic(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- constraint = UniqueConstraint(Random(), name='func_random_uq')
+ constraint = UniqueConstraint(Random(), name="func_random_uq")
with connection.schema_editor() as editor:
with self.assertRaises(DatabaseError):
editor.add_constraint(Author, constraint)
@@ -2539,7 +2799,7 @@ class SchemaTests(TransactionTestCase):
any(
c["index"]
for c in self.get_constraints("schema_tag").values()
- if c['columns'] == ["slug", "title"]
+ if c["columns"] == ["slug", "title"]
),
False,
)
@@ -2551,7 +2811,7 @@ class SchemaTests(TransactionTestCase):
any(
c["index"]
for c in self.get_constraints("schema_tag").values()
- if c['columns'] == ["slug", "title"]
+ if c["columns"] == ["slug", "title"]
),
True,
)
@@ -2565,7 +2825,7 @@ class SchemaTests(TransactionTestCase):
any(
c["index"]
for c in self.get_constraints("schema_tag").values()
- if c['columns'] == ["slug", "title"]
+ if c["columns"] == ["slug", "title"]
),
False,
)
@@ -2583,10 +2843,10 @@ class SchemaTests(TransactionTestCase):
self.assertEqual(Book._meta.index_together, ())
# Add the unique_together constraint
with connection.schema_editor() as editor:
- editor.alter_index_together(Book, [], [['author', 'title']])
+ editor.alter_index_together(Book, [], [["author", "title"]])
# Alter it back
with connection.schema_editor() as editor:
- editor.alter_index_together(Book, [['author', 'title']], [])
+ editor.alter_index_together(Book, [["author", "title"]], [])
def test_create_index_together(self):
"""
@@ -2600,48 +2860,67 @@ class SchemaTests(TransactionTestCase):
any(
c["index"]
for c in self.get_constraints("schema_tagindexed").values()
- if c['columns'] == ["slug", "title"]
+ if c["columns"] == ["slug", "title"]
),
True,
)
- @skipUnlessDBFeature('allows_multiple_constraints_on_same_fields')
+ @skipUnlessDBFeature("allows_multiple_constraints_on_same_fields")
def test_remove_index_together_does_not_remove_meta_indexes(self):
with connection.schema_editor() as editor:
editor.create_model(AuthorWithIndexedNameAndBirthday)
# Add the custom index
- index = Index(fields=['name', 'birthday'], name='author_name_birthday_idx')
+ index = Index(fields=["name", "birthday"], name="author_name_birthday_idx")
custom_index_name = index.name
AuthorWithIndexedNameAndBirthday._meta.indexes = [index]
with connection.schema_editor() as editor:
editor.add_index(AuthorWithIndexedNameAndBirthday, index)
# Ensure the indexes exist
- constraints = self.get_constraints(AuthorWithIndexedNameAndBirthday._meta.db_table)
+ constraints = self.get_constraints(
+ AuthorWithIndexedNameAndBirthday._meta.db_table
+ )
self.assertIn(custom_index_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name', 'birthday'] and details['index'] and name != custom_index_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name", "birthday"]
+ and details["index"]
+ and name != custom_index_name
]
self.assertEqual(len(other_constraints), 1)
# Remove index together
index_together = AuthorWithIndexedNameAndBirthday._meta.index_together
with connection.schema_editor() as editor:
- editor.alter_index_together(AuthorWithIndexedNameAndBirthday, index_together, [])
- constraints = self.get_constraints(AuthorWithIndexedNameAndBirthday._meta.db_table)
+ editor.alter_index_together(
+ AuthorWithIndexedNameAndBirthday, index_together, []
+ )
+ constraints = self.get_constraints(
+ AuthorWithIndexedNameAndBirthday._meta.db_table
+ )
self.assertIn(custom_index_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name', 'birthday'] and details['index'] and name != custom_index_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name", "birthday"]
+ and details["index"]
+ and name != custom_index_name
]
self.assertEqual(len(other_constraints), 0)
# Re-add index together
with connection.schema_editor() as editor:
- editor.alter_index_together(AuthorWithIndexedNameAndBirthday, [], index_together)
- constraints = self.get_constraints(AuthorWithIndexedNameAndBirthday._meta.db_table)
+ editor.alter_index_together(
+ AuthorWithIndexedNameAndBirthday, [], index_together
+ )
+ constraints = self.get_constraints(
+ AuthorWithIndexedNameAndBirthday._meta.db_table
+ )
self.assertIn(custom_index_name, constraints)
other_constraints = [
- name for name, details in constraints.items()
- if details['columns'] == ['name', 'birthday'] and details['index'] and name != custom_index_name
+ name
+ for name, details in constraints.items()
+ if details["columns"] == ["name", "birthday"]
+ and details["index"]
+ and name != custom_index_name
]
self.assertEqual(len(other_constraints), 1)
# Drop the index
@@ -2649,22 +2928,23 @@ class SchemaTests(TransactionTestCase):
AuthorWithIndexedNameAndBirthday._meta.indexes = []
editor.remove_index(AuthorWithIndexedNameAndBirthday, index)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_db_table(self):
"""
Tests renaming of the table
"""
+
class Author(Model):
name = CharField(max_length=255)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class Book(Model):
author = ForeignKey(Author, CASCADE)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
# Create the table and one referring it.
with connection.schema_editor() as editor:
@@ -2672,22 +2952,35 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Book)
# Ensure the table is there to begin with
columns = self.column_classes(Author)
- self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField'])
+ self.assertEqual(
+ columns["name"][0],
+ connection.features.introspected_field_types["CharField"],
+ )
# Alter the table
- with connection.schema_editor(atomic=connection.features.supports_atomic_references_rename) as editor:
+ with connection.schema_editor(
+ atomic=connection.features.supports_atomic_references_rename
+ ) as editor:
editor.alter_db_table(Author, "schema_author", "schema_otherauthor")
Author._meta.db_table = "schema_otherauthor"
columns = self.column_classes(Author)
- self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField'])
+ self.assertEqual(
+ columns["name"][0],
+ connection.features.introspected_field_types["CharField"],
+ )
# Ensure the foreign key reference was updated
self.assertForeignKeyExists(Book, "author_id", "schema_otherauthor")
# Alter the table again
- with connection.schema_editor(atomic=connection.features.supports_atomic_references_rename) as editor:
+ with connection.schema_editor(
+ atomic=connection.features.supports_atomic_references_rename
+ ) as editor:
editor.alter_db_table(Author, "schema_otherauthor", "schema_author")
# Ensure the table is still there
Author._meta.db_table = "schema_author"
columns = self.column_classes(Author)
- self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField'])
+ self.assertEqual(
+ columns["name"][0],
+ connection.features.introspected_field_types["CharField"],
+ )
def test_add_remove_index(self):
"""
@@ -2697,16 +2990,16 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Ensure the table is there and has no index
- self.assertNotIn('title', self.get_indexes(Author._meta.db_table))
+ self.assertNotIn("title", self.get_indexes(Author._meta.db_table))
# Add the index
- index = Index(fields=['name'], name='author_title_idx')
+ index = Index(fields=["name"], name="author_title_idx")
with connection.schema_editor() as editor:
editor.add_index(Author, index)
- self.assertIn('name', self.get_indexes(Author._meta.db_table))
+ self.assertIn("name", self.get_indexes(Author._meta.db_table))
# Drop the index
with connection.schema_editor() as editor:
editor.remove_index(Author, index)
- self.assertNotIn('name', self.get_indexes(Author._meta.db_table))
+ self.assertNotIn("name", self.get_indexes(Author._meta.db_table))
def test_remove_db_index_doesnt_remove_custom_indexes(self):
"""
@@ -2715,15 +3008,15 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(AuthorWithIndexedName)
# Ensure the table has its index
- self.assertIn('name', self.get_indexes(AuthorWithIndexedName._meta.db_table))
+ self.assertIn("name", self.get_indexes(AuthorWithIndexedName._meta.db_table))
# Add the custom index
- index = Index(fields=['-name'], name='author_name_idx')
+ index = Index(fields=["-name"], name="author_name_idx")
author_index_name = index.name
with connection.schema_editor() as editor:
db_index_name = editor._create_index_name(
table_name=AuthorWithIndexedName._meta.db_table,
- column_names=('name',),
+ column_names=("name",),
)
try:
AuthorWithIndexedName._meta.indexes = [index]
@@ -2733,11 +3026,13 @@ class SchemaTests(TransactionTestCase):
self.assertIn(author_index_name, old_constraints)
self.assertIn(db_index_name, old_constraints)
# Change name field to db_index=False
- old_field = AuthorWithIndexedName._meta.get_field('name')
+ old_field = AuthorWithIndexedName._meta.get_field("name")
new_field = CharField(max_length=255)
- new_field.set_attributes_from_name('name')
+ new_field.set_attributes_from_name("name")
with connection.schema_editor() as editor:
- editor.alter_field(AuthorWithIndexedName, old_field, new_field, strict=True)
+ editor.alter_field(
+ AuthorWithIndexedName, old_field, new_field, strict=True
+ )
new_constraints = self.get_constraints(AuthorWithIndexedName._meta.db_table)
self.assertNotIn(db_index_name, new_constraints)
# The index from Meta.indexes is still in the database.
@@ -2755,14 +3050,14 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# The table doesn't have an index
- self.assertNotIn('title', self.get_indexes(Author._meta.db_table))
- index_name = 'author_name_idx'
+ self.assertNotIn("title", self.get_indexes(Author._meta.db_table))
+ index_name = "author_name_idx"
# Add the index
- index = Index(fields=['name', '-weight'], name=index_name)
+ index = Index(fields=["name", "-weight"], name=index_name)
with connection.schema_editor() as editor:
editor.add_index(Author, index)
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(Author._meta.db_table, index_name, ['ASC', 'DESC'])
+ self.assertIndexOrder(Author._meta.db_table, index_name, ["ASC", "DESC"])
# Drop the index
with connection.schema_editor() as editor:
editor.remove_index(Author, index)
@@ -2822,19 +3117,28 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(AuthorTextFieldWithIndex)
# The text_field index is present if the database supports it.
- assertion = self.assertIn if connection.features.supports_index_on_text_field else self.assertNotIn
- assertion('text_field', self.get_indexes(AuthorTextFieldWithIndex._meta.db_table))
+ assertion = (
+ self.assertIn
+ if connection.features.supports_index_on_text_field
+ else self.assertNotIn
+ )
+ assertion(
+ "text_field", self.get_indexes(AuthorTextFieldWithIndex._meta.db_table)
+ )
def _index_expressions_wrappers(self):
index_expression = IndexExpression()
index_expression.set_wrapper_classes(connection)
- return ', '.join([
- wrapper_cls.__qualname__ for wrapper_cls in index_expression.wrapper_classes
- ])
+ return ", ".join(
+ [
+ wrapper_cls.__qualname__
+ for wrapper_cls in index_expression.wrapper_classes
+ ]
+ )
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_multiple_wrapper_references(self):
- index = Index(OrderBy(F('name').desc(), descending=True), name='name')
+ index = Index(OrderBy(F("name").desc(), descending=True), name="name")
msg = (
"Multiple references to %s can't be used in an indexed expression."
% self._index_expressions_wrappers()
@@ -2843,42 +3147,42 @@ class SchemaTests(TransactionTestCase):
with self.assertRaisesMessage(ValueError, msg):
editor.add_index(Author, index)
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_invalid_topmost_expressions(self):
- index = Index(Upper(F('name').desc()), name='name')
+ index = Index(Upper(F("name").desc()), name="name")
msg = (
- '%s must be topmost expressions in an indexed expression.'
+ "%s must be topmost expressions in an indexed expression."
% self._index_expressions_wrappers()
)
with connection.schema_editor() as editor:
with self.assertRaisesMessage(ValueError, msg):
editor.add_index(Author, index)
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- index = Index(Lower('name').desc(), name='func_lower_idx')
+ index = Index(Lower("name").desc(), name="func_lower_idx")
# Add index.
with connection.schema_editor() as editor:
editor.add_index(Author, index)
sql = index.create_sql(Author, editor)
table = Author._meta.db_table
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(table, index.name, ['DESC'])
+ self.assertIndexOrder(table, index.name, ["DESC"])
# SQL contains a database function.
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIn('LOWER(%s)' % editor.quote_name('name'), str(sql))
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIn("LOWER(%s)" % editor.quote_name("name"), str(sql))
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Author, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_f(self):
with connection.schema_editor() as editor:
editor.create_model(Tag)
- index = Index('slug', F('title').desc(), name='func_f_idx')
+ index = Index("slug", F("title").desc(), name="func_f_idx")
# Add index.
with connection.schema_editor() as editor:
editor.add_index(Tag, index)
@@ -2886,24 +3190,24 @@ class SchemaTests(TransactionTestCase):
table = Tag._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(Tag._meta.db_table, index.name, ['ASC', 'DESC'])
+ self.assertIndexOrder(Tag._meta.db_table, index.name, ["ASC", "DESC"])
# SQL contains columns.
- self.assertIs(sql.references_column(table, 'slug'), True)
- self.assertIs(sql.references_column(table, 'title'), True)
+ self.assertIs(sql.references_column(table, "slug"), True)
+ self.assertIs(sql.references_column(table, "title"), True)
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Tag, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_lookups(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
with register_lookup(CharField, Lower), register_lookup(IntegerField, Abs):
index = Index(
- F('name__lower'),
- F('weight__abs'),
- name='func_lower_abs_lookup_idx',
+ F("name__lower"),
+ F("weight__abs"),
+ name="func_lower_abs_lookup_idx",
)
# Add index.
with connection.schema_editor() as editor:
@@ -2912,18 +3216,18 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
# SQL contains columns.
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIs(sql.references_column(table, 'weight'), True)
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIs(sql.references_column(table, "weight"), True)
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Author, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_composite_func_index(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- index = Index(Lower('name'), Upper('name'), name='func_lower_upper_idx')
+ index = Index(Lower("name"), Upper("name"), name="func_lower_upper_idx")
# Add index.
with connection.schema_editor() as editor:
editor.add_index(Author, index)
@@ -2931,26 +3235,26 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
# SQL contains database functions.
- self.assertIs(sql.references_column(table, 'name'), True)
+ self.assertIs(sql.references_column(table, "name"), True)
sql = str(sql)
- self.assertIn('LOWER(%s)' % editor.quote_name('name'), sql)
- self.assertIn('UPPER(%s)' % editor.quote_name('name'), sql)
- self.assertLess(sql.index('LOWER'), sql.index('UPPER'))
+ self.assertIn("LOWER(%s)" % editor.quote_name("name"), sql)
+ self.assertIn("UPPER(%s)" % editor.quote_name("name"), sql)
+ self.assertLess(sql.index("LOWER"), sql.index("UPPER"))
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Author, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_composite_func_index_field_and_expression(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(Book)
index = Index(
- F('author').desc(),
- Lower('title').asc(),
- 'pub_date',
- name='func_f_lower_field_idx',
+ F("author").desc(),
+ Lower("title").asc(),
+ "pub_date",
+ name="func_f_lower_field_idx",
)
# Add index.
with connection.schema_editor() as editor:
@@ -2959,76 +3263,74 @@ class SchemaTests(TransactionTestCase):
table = Book._meta.db_table
constraints = self.get_constraints(table)
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(table, index.name, ['DESC', 'ASC', 'ASC'])
- self.assertEqual(len(constraints[index.name]['columns']), 3)
- self.assertEqual(constraints[index.name]['columns'][2], 'pub_date')
+ self.assertIndexOrder(table, index.name, ["DESC", "ASC", "ASC"])
+ self.assertEqual(len(constraints[index.name]["columns"]), 3)
+ self.assertEqual(constraints[index.name]["columns"][2], "pub_date")
# SQL contains database functions and columns.
- self.assertIs(sql.references_column(table, 'author_id'), True)
- self.assertIs(sql.references_column(table, 'title'), True)
- self.assertIs(sql.references_column(table, 'pub_date'), True)
- self.assertIn('LOWER(%s)' % editor.quote_name('title'), str(sql))
+ self.assertIs(sql.references_column(table, "author_id"), True)
+ self.assertIs(sql.references_column(table, "title"), True)
+ self.assertIs(sql.references_column(table, "pub_date"), True)
+ self.assertIn("LOWER(%s)" % editor.quote_name("title"), str(sql))
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Book, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
- @isolate_apps('schema')
+ @skipUnlessDBFeature("supports_expression_indexes")
+ @isolate_apps("schema")
def test_func_index_f_decimalfield(self):
class Node(Model):
value = DecimalField(max_digits=5, decimal_places=2)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Node)
- index = Index(F('value'), name='func_f_decimalfield_idx')
+ index = Index(F("value"), name="func_f_decimalfield_idx")
# Add index.
with connection.schema_editor() as editor:
editor.add_index(Node, index)
sql = index.create_sql(Node, editor)
table = Node._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
- self.assertIs(sql.references_column(table, 'value'), True)
+ self.assertIs(sql.references_column(table, "value"), True)
# SQL doesn't contain casting.
- self.assertNotIn('CAST', str(sql))
+ self.assertNotIn("CAST", str(sql))
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Node, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_cast(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- index = Index(Cast('weight', FloatField()), name='func_cast_idx')
+ index = Index(Cast("weight", FloatField()), name="func_cast_idx")
# Add index.
with connection.schema_editor() as editor:
editor.add_index(Author, index)
sql = index.create_sql(Author, editor)
table = Author._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
- self.assertIs(sql.references_column(table, 'weight'), True)
+ self.assertIs(sql.references_column(table, "weight"), True)
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Author, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_collate(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest(
- 'This backend does not support case-insensitive collations.'
- )
+ self.skipTest("This backend does not support case-insensitive collations.")
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(BookWithSlug)
index = Index(
- Collate(F('title'), collation=collation).desc(),
- Collate('slug', collation=collation),
- name='func_collate_idx',
+ Collate(F("title"), collation=collation).desc(),
+ Collate("slug", collation=collation),
+ name="func_collate_idx",
)
# Add index.
with connection.schema_editor() as editor:
@@ -3037,29 +3339,27 @@ class SchemaTests(TransactionTestCase):
table = Book._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(table, index.name, ['DESC', 'ASC'])
+ self.assertIndexOrder(table, index.name, ["DESC", "ASC"])
# SQL contains columns and a collation.
- self.assertIs(sql.references_column(table, 'title'), True)
- self.assertIs(sql.references_column(table, 'slug'), True)
- self.assertIn('COLLATE %s' % editor.quote_name(collation), str(sql))
+ self.assertIs(sql.references_column(table, "title"), True)
+ self.assertIs(sql.references_column(table, "slug"), True)
+ self.assertIn("COLLATE %s" % editor.quote_name(collation), str(sql))
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Book, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
- @skipIfDBFeature('collate_as_index_expression')
+ @skipUnlessDBFeature("supports_expression_indexes")
+ @skipIfDBFeature("collate_as_index_expression")
def test_func_index_collate_f_ordered(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest(
- 'This backend does not support case-insensitive collations.'
- )
+ self.skipTest("This backend does not support case-insensitive collations.")
with connection.schema_editor() as editor:
editor.create_model(Author)
index = Index(
- Collate(F('name').desc(), collation=collation),
- name='func_collate_f_desc_idx',
+ Collate(F("name").desc(), collation=collation),
+ name="func_collate_f_desc_idx",
)
# Add index.
with connection.schema_editor() as editor:
@@ -3068,20 +3368,20 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
if connection.features.supports_index_column_ordering:
- self.assertIndexOrder(table, index.name, ['DESC'])
+ self.assertIndexOrder(table, index.name, ["DESC"])
# SQL contains columns and a collation.
- self.assertIs(sql.references_column(table, 'name'), True)
- self.assertIn('COLLATE %s' % editor.quote_name(collation), str(sql))
+ self.assertIs(sql.references_column(table, "name"), True)
+ self.assertIn("COLLATE %s" % editor.quote_name(collation), str(sql))
# Remove index.
with connection.schema_editor() as editor:
editor.remove_index(Author, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_calc(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- index = Index(F('height') / (F('weight') + Value(5)), name='func_calc_idx')
+ index = Index(F("height") / (F("weight") + Value(5)), name="func_calc_idx")
# Add index.
with connection.schema_editor() as editor:
editor.add_index(Author, index)
@@ -3089,15 +3389,15 @@ class SchemaTests(TransactionTestCase):
table = Author._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
# SQL contains columns and expressions.
- self.assertIs(sql.references_column(table, 'height'), True)
- self.assertIs(sql.references_column(table, 'weight'), True)
+ self.assertIs(sql.references_column(table, "height"), True)
+ self.assertIs(sql.references_column(table, "weight"), True)
sql = str(sql)
self.assertIs(
- sql.index(editor.quote_name('height')) <
- sql.index('/') <
- sql.index(editor.quote_name('weight')) <
- sql.index('+') <
- sql.index('5'),
+ sql.index(editor.quote_name("height"))
+ < sql.index("/")
+ < sql.index(editor.quote_name("weight"))
+ < sql.index("+")
+ < sql.index("5"),
True,
)
# Remove index.
@@ -3105,69 +3405,69 @@ class SchemaTests(TransactionTestCase):
editor.remove_index(Author, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes', 'supports_json_field')
- @isolate_apps('schema')
+ @skipUnlessDBFeature("supports_expression_indexes", "supports_json_field")
+ @isolate_apps("schema")
def test_func_index_json_key_transform(self):
class JSONModel(Model):
field = JSONField()
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(JSONModel)
self.isolated_local_models = [JSONModel]
- index = Index('field__some_key', name='func_json_key_idx')
+ index = Index("field__some_key", name="func_json_key_idx")
with connection.schema_editor() as editor:
editor.add_index(JSONModel, index)
sql = index.create_sql(JSONModel, editor)
table = JSONModel._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
- self.assertIs(sql.references_column(table, 'field'), True)
+ self.assertIs(sql.references_column(table, "field"), True)
with connection.schema_editor() as editor:
editor.remove_index(JSONModel, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipUnlessDBFeature('supports_expression_indexes', 'supports_json_field')
- @isolate_apps('schema')
+ @skipUnlessDBFeature("supports_expression_indexes", "supports_json_field")
+ @isolate_apps("schema")
def test_func_index_json_key_transform_cast(self):
class JSONModel(Model):
field = JSONField()
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(JSONModel)
self.isolated_local_models = [JSONModel]
index = Index(
- Cast(KeyTextTransform('some_key', 'field'), IntegerField()),
- name='func_json_key_cast_idx',
+ Cast(KeyTextTransform("some_key", "field"), IntegerField()),
+ name="func_json_key_cast_idx",
)
with connection.schema_editor() as editor:
editor.add_index(JSONModel, index)
sql = index.create_sql(JSONModel, editor)
table = JSONModel._meta.db_table
self.assertIn(index.name, self.get_constraints(table))
- self.assertIs(sql.references_column(table, 'field'), True)
+ self.assertIs(sql.references_column(table, "field"), True)
with connection.schema_editor() as editor:
editor.remove_index(JSONModel, index)
self.assertNotIn(index.name, self.get_constraints(table))
- @skipIfDBFeature('supports_expression_indexes')
+ @skipIfDBFeature("supports_expression_indexes")
def test_func_index_unsupported(self):
# Index is ignored on databases that don't support indexes on
# expressions.
with connection.schema_editor() as editor:
editor.create_model(Author)
- index = Index(F('name'), name='random_idx')
+ index = Index(F("name"), name="random_idx")
with connection.schema_editor() as editor, self.assertNumQueries(0):
self.assertIsNone(editor.add_index(Author, index))
self.assertIsNone(editor.remove_index(Author, index))
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_nonexistent_field(self):
- index = Index(Lower('nonexistent'), name='func_nonexistent_idx')
+ index = Index(Lower("nonexistent"), name="func_nonexistent_idx")
msg = (
"Cannot resolve keyword 'nonexistent' into field. Choices are: "
"height, id, name, uuid, weight"
@@ -3176,11 +3476,11 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.add_index(Author, index)
- @skipUnlessDBFeature('supports_expression_indexes')
+ @skipUnlessDBFeature("supports_expression_indexes")
def test_func_index_nondeterministic(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
- index = Index(Random(), name='func_random_idx')
+ index = Index(Random(), name="func_random_idx")
with connection.schema_editor() as editor:
with self.assertRaises(DatabaseError):
editor.add_index(Author, index)
@@ -3193,7 +3493,7 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Tag)
# Ensure the table is there and has the right PK
- self.assertEqual(self.get_primary_key(Tag._meta.db_table), 'id')
+ self.assertEqual(self.get_primary_key(Tag._meta.db_table), "id")
# Alter to change the PK
id_field = Tag._meta.get_field("id")
old_field = Tag._meta.get_field("slug")
@@ -3205,25 +3505,27 @@ class SchemaTests(TransactionTestCase):
editor.alter_field(Tag, old_field, new_field)
# Ensure the PK changed
self.assertNotIn(
- 'id',
+ "id",
self.get_indexes(Tag._meta.db_table),
)
- self.assertEqual(self.get_primary_key(Tag._meta.db_table), 'slug')
+ self.assertEqual(self.get_primary_key(Tag._meta.db_table), "slug")
def test_context_manager_exit(self):
"""
Ensures transaction is correctly closed when an error occurs
inside a SchemaEditor context.
"""
+
class SomeError(Exception):
pass
+
try:
with connection.schema_editor():
raise SomeError
except SomeError:
self.assertFalse(connection.in_atomic_block)
- @skipIfDBFeature('can_rollback_ddl')
+ @skipIfDBFeature("can_rollback_ddl")
def test_unsupported_transactional_ddl_disallowed(self):
message = (
"Executing DDL statements while in a transaction on databases "
@@ -3231,9 +3533,11 @@ class SchemaTests(TransactionTestCase):
)
with atomic(), connection.schema_editor() as editor:
with self.assertRaisesMessage(TransactionManagementError, message):
- editor.execute(editor.sql_create_table % {'table': 'foo', 'definition': ''})
+ editor.execute(
+ editor.sql_create_table % {"table": "foo", "definition": ""}
+ )
- @skipUnlessDBFeature('supports_foreign_keys', 'indexes_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys", "indexes_foreign_keys")
def test_foreign_key_index_long_names_regression(self):
"""
Regression test for #21497.
@@ -3244,7 +3548,9 @@ class SchemaTests(TransactionTestCase):
editor.create_model(AuthorWithEvenLongerName)
editor.create_model(BookWithLongName)
# Find the properly shortened column name
- column_name = connection.ops.quote_name("author_foreign_key_with_really_long_field_name_id")
+ column_name = connection.ops.quote_name(
+ "author_foreign_key_with_really_long_field_name_id"
+ )
column_name = column_name[1:-1].lower() # unquote, and, for Oracle, un-upcase
# Ensure the table is there and has an index on the column
self.assertIn(
@@ -3252,7 +3558,7 @@ class SchemaTests(TransactionTestCase):
self.get_indexes(BookWithLongName._meta.db_table),
)
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_add_foreign_key_long_names(self):
"""
Regression test for #23009.
@@ -3263,39 +3569,47 @@ class SchemaTests(TransactionTestCase):
editor.create_model(AuthorWithEvenLongerName)
editor.create_model(BookWithLongName)
# Add a second FK, this would fail due to long ref name before the fix
- new_field = ForeignKey(AuthorWithEvenLongerName, CASCADE, related_name="something")
- new_field.set_attributes_from_name("author_other_really_long_named_i_mean_so_long_fk")
+ new_field = ForeignKey(
+ AuthorWithEvenLongerName, CASCADE, related_name="something"
+ )
+ new_field.set_attributes_from_name(
+ "author_other_really_long_named_i_mean_so_long_fk"
+ )
with connection.schema_editor() as editor:
editor.add_field(BookWithLongName, new_field)
- @isolate_apps('schema')
- @skipUnlessDBFeature('supports_foreign_keys')
+ @isolate_apps("schema")
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_add_foreign_key_quoted_db_table(self):
class Author(Model):
class Meta:
db_table = '"table_author_double_quoted"'
- app_label = 'schema'
+ app_label = "schema"
class Book(Model):
author = ForeignKey(Author, CASCADE)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(Book)
- if connection.vendor == 'mysql':
- self.assertForeignKeyExists(Book, 'author_id', '"table_author_double_quoted"')
+ if connection.vendor == "mysql":
+ self.assertForeignKeyExists(
+ Book, "author_id", '"table_author_double_quoted"'
+ )
else:
- self.assertForeignKeyExists(Book, 'author_id', 'table_author_double_quoted')
+ self.assertForeignKeyExists(Book, "author_id", "table_author_double_quoted")
def test_add_foreign_object(self):
with connection.schema_editor() as editor:
editor.create_model(BookForeignObj)
- new_field = ForeignObject(Author, on_delete=CASCADE, from_fields=['author_id'], to_fields=['id'])
- new_field.set_attributes_from_name('author')
+ new_field = ForeignObject(
+ Author, on_delete=CASCADE, from_fields=["author_id"], to_fields=["id"]
+ )
+ new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.add_field(BookForeignObj, new_field)
@@ -3309,8 +3623,10 @@ class SchemaTests(TransactionTestCase):
try:
editor.create_model(Thing)
except OperationalError as e:
- self.fail("Errors when applying initial migration for a model "
- "with a table named after an SQL reserved word: %s" % e)
+ self.fail(
+ "Errors when applying initial migration for a model "
+ "with a table named after an SQL reserved word: %s" % e
+ )
# The table is there
list(Thing.objects.all())
# Clean up that table
@@ -3324,8 +3640,9 @@ class SchemaTests(TransactionTestCase):
"""
#23065 - Constraint names must be quoted if they contain capital letters.
"""
+
def get_field(*args, field_class=IntegerField, **kwargs):
- kwargs['db_column'] = "CamelCase"
+ kwargs["db_column"] = "CamelCase"
field = field_class(*args, **kwargs)
field.set_attributes_from_name("CamelCase")
return field
@@ -3340,10 +3657,11 @@ class SchemaTests(TransactionTestCase):
editor.create_model(model)
editor.add_field(model, field)
- constraint_name = 'CamelCaseIndex'
+ constraint_name = "CamelCaseIndex"
expected_constraint_name = identifier_converter(constraint_name)
editor.execute(
- editor.sql_create_index % {
+ editor.sql_create_index
+ % {
"table": editor.quote_name(table),
"name": editor.quote_name(constraint_name),
"using": "",
@@ -3353,22 +3671,31 @@ class SchemaTests(TransactionTestCase):
"include": "",
}
)
- self.assertIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
+ self.assertIn(
+ expected_constraint_name, self.get_constraints(model._meta.db_table)
+ )
editor.alter_field(model, get_field(db_index=True), field, strict=True)
- self.assertNotIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
+ self.assertNotIn(
+ expected_constraint_name, self.get_constraints(model._meta.db_table)
+ )
- constraint_name = 'CamelCaseUniqConstraint'
+ constraint_name = "CamelCaseUniqConstraint"
expected_constraint_name = identifier_converter(constraint_name)
editor.execute(editor._create_unique_sql(model, [field], constraint_name))
- self.assertIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
+ self.assertIn(
+ expected_constraint_name, self.get_constraints(model._meta.db_table)
+ )
editor.alter_field(model, get_field(unique=True), field, strict=True)
- self.assertNotIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
+ self.assertNotIn(
+ expected_constraint_name, self.get_constraints(model._meta.db_table)
+ )
if editor.sql_create_fk:
- constraint_name = 'CamelCaseFKConstraint'
+ constraint_name = "CamelCaseFKConstraint"
expected_constraint_name = identifier_converter(constraint_name)
editor.execute(
- editor.sql_create_fk % {
+ editor.sql_create_fk
+ % {
"table": editor.quote_name(table),
"name": editor.quote_name(constraint_name),
"column": editor.quote_name(column),
@@ -3377,9 +3704,18 @@ class SchemaTests(TransactionTestCase):
"deferrable": connection.ops.deferrable_sql(),
}
)
- self.assertIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
- editor.alter_field(model, get_field(Author, CASCADE, field_class=ForeignKey), field, strict=True)
- self.assertNotIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
+ self.assertIn(
+ expected_constraint_name, self.get_constraints(model._meta.db_table)
+ )
+ editor.alter_field(
+ model,
+ get_field(Author, CASCADE, field_class=ForeignKey),
+ field,
+ strict=True,
+ )
+ self.assertNotIn(
+ expected_constraint_name, self.get_constraints(model._meta.db_table)
+ )
def test_add_field_use_effective_default(self):
"""
@@ -3393,7 +3729,7 @@ class SchemaTests(TransactionTestCase):
columns = self.column_classes(Author)
self.assertNotIn("surname", columns)
# Create a row
- Author.objects.create(name='Anonymous1')
+ Author.objects.create(name="Anonymous1")
# Add new CharField to ensure default will be used from effective_default
new_field = CharField(max_length=15, blank=True)
new_field.set_attributes_from_name("surname")
@@ -3403,7 +3739,10 @@ class SchemaTests(TransactionTestCase):
with connection.cursor() as cursor:
cursor.execute("SELECT surname FROM schema_author;")
item = cursor.fetchall()[0]
- self.assertEqual(item[0], None if connection.features.interprets_empty_strings_as_nulls else '')
+ self.assertEqual(
+ item[0],
+ None if connection.features.interprets_empty_strings_as_nulls else "",
+ )
def test_add_field_default_dropped(self):
# Create the table
@@ -3413,9 +3752,9 @@ class SchemaTests(TransactionTestCase):
columns = self.column_classes(Author)
self.assertNotIn("surname", columns)
# Create a row
- Author.objects.create(name='Anonymous1')
+ Author.objects.create(name="Anonymous1")
# Add new CharField with a default
- new_field = CharField(max_length=15, blank=True, default='surname default')
+ new_field = CharField(max_length=15, blank=True, default="surname default")
new_field.set_attributes_from_name("surname")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
@@ -3423,10 +3762,13 @@ class SchemaTests(TransactionTestCase):
with connection.cursor() as cursor:
cursor.execute("SELECT surname FROM schema_author;")
item = cursor.fetchall()[0]
- self.assertEqual(item[0], 'surname default')
+ self.assertEqual(item[0], "surname default")
# And that the default is no longer set in the database.
field = next(
- f for f in connection.introspection.get_table_description(cursor, "schema_author")
+ f
+ for f in connection.introspection.get_table_description(
+ cursor, "schema_author"
+ )
if f.name == "surname"
)
if connection.features.can_introspect_default:
@@ -3436,74 +3778,77 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Add new nullable CharField with a default.
- new_field = CharField(max_length=15, blank=True, null=True, default='surname')
- new_field.set_attributes_from_name('surname')
+ new_field = CharField(max_length=15, blank=True, null=True, default="surname")
+ new_field.set_attributes_from_name("surname")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
- Author.objects.create(name='Anonymous1')
+ Author.objects.create(name="Anonymous1")
with connection.cursor() as cursor:
- cursor.execute('SELECT surname FROM schema_author;')
+ cursor.execute("SELECT surname FROM schema_author;")
item = cursor.fetchall()[0]
self.assertIsNone(item[0])
field = next(
f
for f in connection.introspection.get_table_description(
cursor,
- 'schema_author',
+ "schema_author",
)
- if f.name == 'surname'
+ if f.name == "surname"
)
# Field is still nullable.
self.assertTrue(field.null_ok)
# The database default is no longer set.
if connection.features.can_introspect_default:
- self.assertIn(field.default, ['NULL', None])
+ self.assertIn(field.default, ["NULL", None])
def test_add_textfield_default_nullable(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Add new nullable TextField with a default.
- new_field = TextField(blank=True, null=True, default='text')
- new_field.set_attributes_from_name('description')
+ new_field = TextField(blank=True, null=True, default="text")
+ new_field.set_attributes_from_name("description")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
- Author.objects.create(name='Anonymous1')
+ Author.objects.create(name="Anonymous1")
with connection.cursor() as cursor:
- cursor.execute('SELECT description FROM schema_author;')
+ cursor.execute("SELECT description FROM schema_author;")
item = cursor.fetchall()[0]
self.assertIsNone(item[0])
field = next(
f
for f in connection.introspection.get_table_description(
cursor,
- 'schema_author',
+ "schema_author",
)
- if f.name == 'description'
+ if f.name == "description"
)
# Field is still nullable.
self.assertTrue(field.null_ok)
# The database default is no longer set.
if connection.features.can_introspect_default:
- self.assertIn(field.default, ['NULL', None])
+ self.assertIn(field.default, ["NULL", None])
def test_alter_field_default_dropped(self):
# Create the table
with connection.schema_editor() as editor:
editor.create_model(Author)
# Create a row
- Author.objects.create(name='Anonymous1')
+ Author.objects.create(name="Anonymous1")
self.assertIsNone(Author.objects.get().height)
- old_field = Author._meta.get_field('height')
+ old_field = Author._meta.get_field("height")
# The default from the new field is used in updating existing rows.
new_field = IntegerField(blank=True, default=42)
- new_field.set_attributes_from_name('height')
+ new_field.set_attributes_from_name("height")
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
self.assertEqual(Author.objects.get().height, 42)
# The database default should be removed.
with connection.cursor() as cursor:
field = next(
- f for f in connection.introspection.get_table_description(cursor, "schema_author")
+ f
+ for f in connection.introspection.get_table_description(
+ cursor, "schema_author"
+ )
if f.name == "height"
)
if connection.features.can_introspect_default:
@@ -3516,14 +3861,16 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(AuthorWithDefaultHeight)
- old_field = AuthorWithDefaultHeight._meta.get_field('height')
+ old_field = AuthorWithDefaultHeight._meta.get_field("height")
new_default = old_field.default * 2
new_field = PositiveIntegerField(null=True, blank=True, default=new_default)
- new_field.set_attributes_from_name('height')
+ new_field.set_attributes_from_name("height")
with connection.schema_editor() as editor, self.assertNumQueries(0):
- editor.alter_field(AuthorWithDefaultHeight, old_field, new_field, strict=True)
+ editor.alter_field(
+ AuthorWithDefaultHeight, old_field, new_field, strict=True
+ )
- @skipUnlessDBFeature('supports_foreign_keys')
+ @skipUnlessDBFeature("supports_foreign_keys")
def test_alter_field_fk_attributes_noop(self):
"""
No queries are performed when changing field attributes that don't
@@ -3532,21 +3879,21 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(Book)
- old_field = Book._meta.get_field('author')
+ old_field = Book._meta.get_field("author")
new_field = ForeignKey(
Author,
blank=True,
editable=False,
- error_messages={'invalid': 'error message'},
- help_text='help text',
- limit_choices_to={'limit': 'choice'},
+ error_messages={"invalid": "error message"},
+ help_text="help text",
+ limit_choices_to={"limit": "choice"},
on_delete=PROTECT,
- related_name='related_name',
- related_query_name='related_query_name',
+ related_name="related_name",
+ related_query_name="related_query_name",
validators=[lambda x: x],
- verbose_name='verbose name',
+ verbose_name="verbose name",
)
- new_field.set_attributes_from_name('author')
+ new_field.set_attributes_from_name("author")
with connection.schema_editor() as editor, self.assertNumQueries(0):
editor.alter_field(Book, old_field, new_field, strict=True)
with connection.schema_editor() as editor, self.assertNumQueries(0):
@@ -3557,233 +3904,244 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Create a row
- Author.objects.create(name='Anonymous1')
+ Author.objects.create(name="Anonymous1")
# Create a field that has an unhashable default
new_field = TextField(default={})
new_field.set_attributes_from_name("info")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_add_indexed_charfield(self):
field = CharField(max_length=255, db_index=True)
- field.set_attributes_from_name('nom_de_plume')
+ field.set_attributes_from_name("nom_de_plume")
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.add_field(Author, field)
# Should create two indexes; one for like operator.
self.assertEqual(
- self.get_constraints_for_column(Author, 'nom_de_plume'),
- ['schema_author_nom_de_plume_7570a851', 'schema_author_nom_de_plume_7570a851_like'],
+ self.get_constraints_for_column(Author, "nom_de_plume"),
+ [
+ "schema_author_nom_de_plume_7570a851",
+ "schema_author_nom_de_plume_7570a851_like",
+ ],
)
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_add_unique_charfield(self):
field = CharField(max_length=255, unique=True)
- field.set_attributes_from_name('nom_de_plume')
+ field.set_attributes_from_name("nom_de_plume")
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.add_field(Author, field)
# Should create two indexes; one for like operator.
self.assertEqual(
- self.get_constraints_for_column(Author, 'nom_de_plume'),
- ['schema_author_nom_de_plume_7570a851_like', 'schema_author_nom_de_plume_key']
+ self.get_constraints_for_column(Author, "nom_de_plume"),
+ [
+ "schema_author_nom_de_plume_7570a851_like",
+ "schema_author_nom_de_plume_key",
+ ],
)
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_add_index_to_charfield(self):
# Create the table and verify no initial indexes.
with connection.schema_editor() as editor:
editor.create_model(Author)
- self.assertEqual(self.get_constraints_for_column(Author, 'name'), [])
+ self.assertEqual(self.get_constraints_for_column(Author, "name"), [])
# Alter to add db_index=True and create 2 indexes.
- old_field = Author._meta.get_field('name')
+ old_field = Author._meta.get_field("name")
new_field = CharField(max_length=255, db_index=True)
- new_field.set_attributes_from_name('name')
+ new_field.set_attributes_from_name("name")
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
self.assertEqual(
- self.get_constraints_for_column(Author, 'name'),
- ['schema_author_name_1fbc5617', 'schema_author_name_1fbc5617_like']
+ self.get_constraints_for_column(Author, "name"),
+ ["schema_author_name_1fbc5617", "schema_author_name_1fbc5617_like"],
)
# Remove db_index=True to drop both indexes.
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, old_field, strict=True)
- self.assertEqual(self.get_constraints_for_column(Author, 'name'), [])
+ self.assertEqual(self.get_constraints_for_column(Author, "name"), [])
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_add_unique_to_charfield(self):
# Create the table and verify no initial indexes.
with connection.schema_editor() as editor:
editor.create_model(Author)
- self.assertEqual(self.get_constraints_for_column(Author, 'name'), [])
+ self.assertEqual(self.get_constraints_for_column(Author, "name"), [])
# Alter to add unique=True and create 2 indexes.
- old_field = Author._meta.get_field('name')
+ old_field = Author._meta.get_field("name")
new_field = CharField(max_length=255, unique=True)
- new_field.set_attributes_from_name('name')
+ new_field.set_attributes_from_name("name")
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
self.assertEqual(
- self.get_constraints_for_column(Author, 'name'),
- ['schema_author_name_1fbc5617_like', 'schema_author_name_1fbc5617_uniq']
+ self.get_constraints_for_column(Author, "name"),
+ ["schema_author_name_1fbc5617_like", "schema_author_name_1fbc5617_uniq"],
)
# Remove unique=True to drop both indexes.
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, old_field, strict=True)
- self.assertEqual(self.get_constraints_for_column(Author, 'name'), [])
+ self.assertEqual(self.get_constraints_for_column(Author, "name"), [])
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_add_index_to_textfield(self):
# Create the table and verify no initial indexes.
with connection.schema_editor() as editor:
editor.create_model(Note)
- self.assertEqual(self.get_constraints_for_column(Note, 'info'), [])
+ self.assertEqual(self.get_constraints_for_column(Note, "info"), [])
# Alter to add db_index=True and create 2 indexes.
- old_field = Note._meta.get_field('info')
+ old_field = Note._meta.get_field("info")
new_field = TextField(db_index=True)
- new_field.set_attributes_from_name('info')
+ new_field.set_attributes_from_name("info")
with connection.schema_editor() as editor:
editor.alter_field(Note, old_field, new_field, strict=True)
self.assertEqual(
- self.get_constraints_for_column(Note, 'info'),
- ['schema_note_info_4b0ea695', 'schema_note_info_4b0ea695_like']
+ self.get_constraints_for_column(Note, "info"),
+ ["schema_note_info_4b0ea695", "schema_note_info_4b0ea695_like"],
)
# Remove db_index=True to drop both indexes.
with connection.schema_editor() as editor:
editor.alter_field(Note, new_field, old_field, strict=True)
- self.assertEqual(self.get_constraints_for_column(Note, 'info'), [])
+ self.assertEqual(self.get_constraints_for_column(Note, "info"), [])
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_add_unique_to_charfield_with_db_index(self):
# Create the table and verify initial indexes.
with connection.schema_editor() as editor:
editor.create_model(BookWithoutAuthor)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff', 'schema_book_title_2dfb2dff_like']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff", "schema_book_title_2dfb2dff_like"],
)
# Alter to add unique=True (should replace the index)
- old_field = BookWithoutAuthor._meta.get_field('title')
+ old_field = BookWithoutAuthor._meta.get_field("title")
new_field = CharField(max_length=100, db_index=True, unique=True)
- new_field.set_attributes_from_name('title')
+ new_field.set_attributes_from_name("title")
with connection.schema_editor() as editor:
editor.alter_field(BookWithoutAuthor, old_field, new_field, strict=True)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff_like', 'schema_book_title_2dfb2dff_uniq']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff_like", "schema_book_title_2dfb2dff_uniq"],
)
# Alter to remove unique=True (should drop unique index)
new_field2 = CharField(max_length=100, db_index=True)
- new_field2.set_attributes_from_name('title')
+ new_field2.set_attributes_from_name("title")
with connection.schema_editor() as editor:
editor.alter_field(BookWithoutAuthor, new_field, new_field2, strict=True)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff', 'schema_book_title_2dfb2dff_like']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff", "schema_book_title_2dfb2dff_like"],
)
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_remove_unique_and_db_index_from_charfield(self):
# Create the table and verify initial indexes.
with connection.schema_editor() as editor:
editor.create_model(BookWithoutAuthor)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff', 'schema_book_title_2dfb2dff_like']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff", "schema_book_title_2dfb2dff_like"],
)
# Alter to add unique=True (should replace the index)
- old_field = BookWithoutAuthor._meta.get_field('title')
+ old_field = BookWithoutAuthor._meta.get_field("title")
new_field = CharField(max_length=100, db_index=True, unique=True)
- new_field.set_attributes_from_name('title')
+ new_field.set_attributes_from_name("title")
with connection.schema_editor() as editor:
editor.alter_field(BookWithoutAuthor, old_field, new_field, strict=True)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff_like', 'schema_book_title_2dfb2dff_uniq']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff_like", "schema_book_title_2dfb2dff_uniq"],
)
# Alter to remove both unique=True and db_index=True (should drop all indexes)
new_field2 = CharField(max_length=100)
- new_field2.set_attributes_from_name('title')
+ new_field2.set_attributes_from_name("title")
with connection.schema_editor() as editor:
editor.alter_field(BookWithoutAuthor, new_field, new_field2, strict=True)
- self.assertEqual(self.get_constraints_for_column(BookWithoutAuthor, 'title'), [])
+ self.assertEqual(
+ self.get_constraints_for_column(BookWithoutAuthor, "title"), []
+ )
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_swap_unique_and_db_index_with_charfield(self):
# Create the table and verify initial indexes.
with connection.schema_editor() as editor:
editor.create_model(BookWithoutAuthor)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff', 'schema_book_title_2dfb2dff_like']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff", "schema_book_title_2dfb2dff_like"],
)
# Alter to set unique=True and remove db_index=True (should replace the index)
- old_field = BookWithoutAuthor._meta.get_field('title')
+ old_field = BookWithoutAuthor._meta.get_field("title")
new_field = CharField(max_length=100, unique=True)
- new_field.set_attributes_from_name('title')
+ new_field.set_attributes_from_name("title")
with connection.schema_editor() as editor:
editor.alter_field(BookWithoutAuthor, old_field, new_field, strict=True)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff_like', 'schema_book_title_2dfb2dff_uniq']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff_like", "schema_book_title_2dfb2dff_uniq"],
)
# Alter to set db_index=True and remove unique=True (should restore index)
new_field2 = CharField(max_length=100, db_index=True)
- new_field2.set_attributes_from_name('title')
+ new_field2.set_attributes_from_name("title")
with connection.schema_editor() as editor:
editor.alter_field(BookWithoutAuthor, new_field, new_field2, strict=True)
self.assertEqual(
- self.get_constraints_for_column(BookWithoutAuthor, 'title'),
- ['schema_book_title_2dfb2dff', 'schema_book_title_2dfb2dff_like']
+ self.get_constraints_for_column(BookWithoutAuthor, "title"),
+ ["schema_book_title_2dfb2dff", "schema_book_title_2dfb2dff_like"],
)
- @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific")
+ @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific")
def test_alter_field_add_db_index_to_charfield_with_unique(self):
# Create the table and verify initial indexes.
with connection.schema_editor() as editor:
editor.create_model(Tag)
self.assertEqual(
- self.get_constraints_for_column(Tag, 'slug'),
- ['schema_tag_slug_2c418ba3_like', 'schema_tag_slug_key']
+ self.get_constraints_for_column(Tag, "slug"),
+ ["schema_tag_slug_2c418ba3_like", "schema_tag_slug_key"],
)
# Alter to add db_index=True
- old_field = Tag._meta.get_field('slug')
+ old_field = Tag._meta.get_field("slug")
new_field = SlugField(db_index=True, unique=True)
- new_field.set_attributes_from_name('slug')
+ new_field.set_attributes_from_name("slug")
with connection.schema_editor() as editor:
editor.alter_field(Tag, old_field, new_field, strict=True)
self.assertEqual(
- self.get_constraints_for_column(Tag, 'slug'),
- ['schema_tag_slug_2c418ba3_like', 'schema_tag_slug_key']
+ self.get_constraints_for_column(Tag, "slug"),
+ ["schema_tag_slug_2c418ba3_like", "schema_tag_slug_key"],
)
# Alter to remove db_index=True
new_field2 = SlugField(unique=True)
- new_field2.set_attributes_from_name('slug')
+ new_field2.set_attributes_from_name("slug")
with connection.schema_editor() as editor:
editor.alter_field(Tag, new_field, new_field2, strict=True)
self.assertEqual(
- self.get_constraints_for_column(Tag, 'slug'),
- ['schema_tag_slug_2c418ba3_like', 'schema_tag_slug_key']
+ self.get_constraints_for_column(Tag, "slug"),
+ ["schema_tag_slug_2c418ba3_like", "schema_tag_slug_key"],
)
def test_alter_field_add_index_to_integerfield(self):
# Create the table and verify no initial indexes.
with connection.schema_editor() as editor:
editor.create_model(Author)
- self.assertEqual(self.get_constraints_for_column(Author, 'weight'), [])
+ self.assertEqual(self.get_constraints_for_column(Author, "weight"), [])
# Alter to add db_index=True and create index.
- old_field = Author._meta.get_field('weight')
+ old_field = Author._meta.get_field("weight")
new_field = IntegerField(null=True, db_index=True)
- new_field.set_attributes_from_name('weight')
+ new_field.set_attributes_from_name("weight")
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
- self.assertEqual(self.get_constraints_for_column(Author, 'weight'), ['schema_author_weight_587740f9'])
+ self.assertEqual(
+ self.get_constraints_for_column(Author, "weight"),
+ ["schema_author_weight_587740f9"],
+ )
# Remove db_index=True to drop index.
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, old_field, strict=True)
- self.assertEqual(self.get_constraints_for_column(Author, 'weight'), [])
+ self.assertEqual(self.get_constraints_for_column(Author, "weight"), [])
def test_alter_pk_with_self_referential_field(self):
"""
@@ -3792,22 +4150,26 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
editor.create_model(Node)
- old_field = Node._meta.get_field('node_id')
+ old_field = Node._meta.get_field("node_id")
new_field = AutoField(primary_key=True)
- new_field.set_attributes_from_name('id')
+ new_field.set_attributes_from_name("id")
with connection.schema_editor() as editor:
editor.alter_field(Node, old_field, new_field, strict=True)
- self.assertForeignKeyExists(Node, 'parent_id', Node._meta.db_table)
+ self.assertForeignKeyExists(Node, "parent_id", Node._meta.db_table)
- @mock.patch('django.db.backends.base.schema.datetime')
- @mock.patch('django.db.backends.base.schema.timezone')
- def test_add_datefield_and_datetimefield_use_effective_default(self, mocked_datetime, mocked_tz):
+ @mock.patch("django.db.backends.base.schema.datetime")
+ @mock.patch("django.db.backends.base.schema.timezone")
+ def test_add_datefield_and_datetimefield_use_effective_default(
+ self, mocked_datetime, mocked_tz
+ ):
"""
effective_default() should be used for DateField, DateTimeField, and
TimeField if auto_now or auto_now_add is set (#25005).
"""
now = datetime.datetime(month=1, day=1, year=2000, hour=1, minute=1)
- now_tz = datetime.datetime(month=1, day=1, year=2000, hour=1, minute=1, tzinfo=timezone.utc)
+ now_tz = datetime.datetime(
+ month=1, day=1, year=2000, hour=1, minute=1, tzinfo=timezone.utc
+ )
mocked_datetime.now = mock.MagicMock(return_value=now)
mocked_tz.now = mock.MagicMock(return_value=now_tz)
# Create the table
@@ -3822,40 +4184,64 @@ class SchemaTests(TransactionTestCase):
self.assertNotIn("tob_auto_now", columns)
self.assertNotIn("tob_auto_now_add", columns)
# Create a row
- Author.objects.create(name='Anonymous1')
+ Author.objects.create(name="Anonymous1")
# Ensure fields were added with the correct defaults
dob_auto_now = DateField(auto_now=True)
- dob_auto_now.set_attributes_from_name('dob_auto_now')
+ dob_auto_now.set_attributes_from_name("dob_auto_now")
self.check_added_field_default(
- editor, Author, dob_auto_now, 'dob_auto_now', now.date(),
+ editor,
+ Author,
+ dob_auto_now,
+ "dob_auto_now",
+ now.date(),
cast_function=lambda x: x.date(),
)
dob_auto_now_add = DateField(auto_now_add=True)
- dob_auto_now_add.set_attributes_from_name('dob_auto_now_add')
+ dob_auto_now_add.set_attributes_from_name("dob_auto_now_add")
self.check_added_field_default(
- editor, Author, dob_auto_now_add, 'dob_auto_now_add', now.date(),
+ editor,
+ Author,
+ dob_auto_now_add,
+ "dob_auto_now_add",
+ now.date(),
cast_function=lambda x: x.date(),
)
dtob_auto_now = DateTimeField(auto_now=True)
- dtob_auto_now.set_attributes_from_name('dtob_auto_now')
+ dtob_auto_now.set_attributes_from_name("dtob_auto_now")
self.check_added_field_default(
- editor, Author, dtob_auto_now, 'dtob_auto_now', now,
+ editor,
+ Author,
+ dtob_auto_now,
+ "dtob_auto_now",
+ now,
)
dt_tm_of_birth_auto_now_add = DateTimeField(auto_now_add=True)
- dt_tm_of_birth_auto_now_add.set_attributes_from_name('dtob_auto_now_add')
+ dt_tm_of_birth_auto_now_add.set_attributes_from_name("dtob_auto_now_add")
self.check_added_field_default(
- editor, Author, dt_tm_of_birth_auto_now_add, 'dtob_auto_now_add', now,
+ editor,
+ Author,
+ dt_tm_of_birth_auto_now_add,
+ "dtob_auto_now_add",
+ now,
)
tob_auto_now = TimeField(auto_now=True)
- tob_auto_now.set_attributes_from_name('tob_auto_now')
+ tob_auto_now.set_attributes_from_name("tob_auto_now")
self.check_added_field_default(
- editor, Author, tob_auto_now, 'tob_auto_now', now.time(),
+ editor,
+ Author,
+ tob_auto_now,
+ "tob_auto_now",
+ now.time(),
cast_function=lambda x: x.time(),
)
tob_auto_now_add = TimeField(auto_now_add=True)
- tob_auto_now_add.set_attributes_from_name('tob_auto_now_add')
+ tob_auto_now_add.set_attributes_from_name("tob_auto_now_add")
self.check_added_field_default(
- editor, Author, tob_auto_now_add, 'tob_auto_now_add', now.time(),
+ editor,
+ Author,
+ tob_auto_now_add,
+ "tob_auto_now_add",
+ now.time(),
cast_function=lambda x: x.time(),
)
@@ -3866,15 +4252,17 @@ class SchemaTests(TransactionTestCase):
"""
with connection.schema_editor() as editor:
max_name_length = connection.ops.max_name_length() or 200
- namespace = 'n' * max_name_length
- table_name = 't' * max_name_length
+ namespace = "n" * max_name_length
+ table_name = "t" * max_name_length
namespaced_table_name = '"%s"."%s"' % (namespace, table_name)
self.assertEqual(
editor._create_index_name(table_name, []),
editor._create_index_name(namespaced_table_name, []),
)
- @unittest.skipUnless(connection.vendor == 'oracle', 'Oracle specific db_table syntax')
+ @unittest.skipUnless(
+ connection.vendor == "oracle", "Oracle specific db_table syntax"
+ )
def test_creation_with_db_table_double_quotes(self):
oracle_user = connection.creation._test_database_user()
@@ -3882,7 +4270,7 @@ class SchemaTests(TransactionTestCase):
name = CharField(max_length=30)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
db_table = '"%s"."DJANGO_STUDENT_TABLE"' % oracle_user
@@ -3891,7 +4279,7 @@ class SchemaTests(TransactionTestCase):
students = ManyToManyField(Student)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
apps = new_apps
db_table = '"%s"."DJANGO_DOCUMENT_TABLE"' % oracle_user
@@ -3901,33 +4289,35 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Student)
editor.create_model(Document)
- doc = Document.objects.create(name='Test Name')
- student = Student.objects.create(name='Some man')
+ doc = Document.objects.create(name="Test Name")
+ student = Student.objects.create(name="Some man")
doc.students.add(student)
- @isolate_apps('schema')
- @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific db_table syntax.')
+ @isolate_apps("schema")
+ @unittest.skipUnless(
+ connection.vendor == "postgresql", "PostgreSQL specific db_table syntax."
+ )
def test_namespaced_db_table_foreign_key_reference(self):
with connection.cursor() as cursor:
- cursor.execute('CREATE SCHEMA django_schema_tests')
+ cursor.execute("CREATE SCHEMA django_schema_tests")
def delete_schema():
with connection.cursor() as cursor:
- cursor.execute('DROP SCHEMA django_schema_tests CASCADE')
+ cursor.execute("DROP SCHEMA django_schema_tests CASCADE")
self.addCleanup(delete_schema)
class Author(Model):
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class Book(Model):
class Meta:
- app_label = 'schema'
+ app_label = "schema"
db_table = '"django_schema_tests"."schema_book"'
author = ForeignKey(Author, CASCADE)
- author.set_attributes_from_name('author')
+ author.set_attributes_from_name("author")
with connection.schema_editor() as editor:
editor.create_model(Author)
@@ -3939,51 +4329,52 @@ class SchemaTests(TransactionTestCase):
with connection.schema_editor(atomic=atomic_rename) as editor:
editor.create_model(Author)
editor.create_model(Book)
- editor.alter_db_table(Author, 'schema_author', 'schema_renamed_author')
- editor.alter_db_table(Author, 'schema_book', 'schema_renamed_book')
+ editor.alter_db_table(Author, "schema_author", "schema_renamed_author")
+ editor.alter_db_table(Author, "schema_book", "schema_renamed_book")
try:
self.assertGreater(len(editor.deferred_sql), 0)
for statement in editor.deferred_sql:
- self.assertIs(statement.references_table('schema_author'), False)
- self.assertIs(statement.references_table('schema_book'), False)
+ self.assertIs(statement.references_table("schema_author"), False)
+ self.assertIs(statement.references_table("schema_book"), False)
finally:
- editor.alter_db_table(Author, 'schema_renamed_author', 'schema_author')
- editor.alter_db_table(Author, 'schema_renamed_book', 'schema_book')
+ editor.alter_db_table(Author, "schema_renamed_author", "schema_author")
+ editor.alter_db_table(Author, "schema_renamed_book", "schema_book")
def test_rename_column_renames_deferred_sql_references(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(Book)
- old_title = Book._meta.get_field('title')
+ old_title = Book._meta.get_field("title")
new_title = CharField(max_length=100, db_index=True)
- new_title.set_attributes_from_name('renamed_title')
+ new_title.set_attributes_from_name("renamed_title")
editor.alter_field(Book, old_title, new_title)
- old_author = Book._meta.get_field('author')
+ old_author = Book._meta.get_field("author")
new_author = ForeignKey(Author, CASCADE)
- new_author.set_attributes_from_name('renamed_author')
+ new_author.set_attributes_from_name("renamed_author")
editor.alter_field(Book, old_author, new_author)
self.assertGreater(len(editor.deferred_sql), 0)
for statement in editor.deferred_sql:
- self.assertIs(statement.references_column('book', 'title'), False)
- self.assertIs(statement.references_column('book', 'author_id'), False)
+ self.assertIs(statement.references_column("book", "title"), False)
+ self.assertIs(statement.references_column("book", "author_id"), False)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_referenced_field_without_constraint_rename_inside_atomic_block(self):
"""
Foreign keys without database level constraint don't prevent the field
they reference from being renamed in an atomic block.
"""
+
class Foo(Model):
field = CharField(max_length=255, unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class Bar(Model):
- foo = ForeignKey(Foo, CASCADE, to_field='field', db_constraint=False)
+ foo = ForeignKey(Foo, CASCADE, to_field="field", db_constraint=False)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
self.isolated_local_models = [Foo, Bar]
with connection.schema_editor() as editor:
@@ -3991,27 +4382,28 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Bar)
new_field = CharField(max_length=255, unique=True)
- new_field.set_attributes_from_name('renamed')
+ new_field.set_attributes_from_name("renamed")
with connection.schema_editor(atomic=True) as editor:
- editor.alter_field(Foo, Foo._meta.get_field('field'), new_field)
+ editor.alter_field(Foo, Foo._meta.get_field("field"), new_field)
- @isolate_apps('schema')
+ @isolate_apps("schema")
def test_referenced_table_without_constraint_rename_inside_atomic_block(self):
"""
Foreign keys without database level constraint don't prevent the table
they reference from being renamed in an atomic block.
"""
+
class Foo(Model):
field = CharField(max_length=255, unique=True)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
class Bar(Model):
- foo = ForeignKey(Foo, CASCADE, to_field='field', db_constraint=False)
+ foo = ForeignKey(Foo, CASCADE, to_field="field", db_constraint=False)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
self.isolated_local_models = [Foo, Bar]
with connection.schema_editor() as editor:
@@ -4019,164 +4411,164 @@ class SchemaTests(TransactionTestCase):
editor.create_model(Bar)
new_field = CharField(max_length=255, unique=True)
- new_field.set_attributes_from_name('renamed')
+ new_field.set_attributes_from_name("renamed")
with connection.schema_editor(atomic=True) as editor:
- editor.alter_db_table(Foo, Foo._meta.db_table, 'renamed_table')
- Foo._meta.db_table = 'renamed_table'
+ editor.alter_db_table(Foo, Foo._meta.db_table, "renamed_table")
+ Foo._meta.db_table = "renamed_table"
- @isolate_apps('schema')
- @skipUnlessDBFeature('supports_collation_on_charfield')
+ @isolate_apps("schema")
+ @skipUnlessDBFeature("supports_collation_on_charfield")
def test_db_collation_charfield(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest('Language collations are not supported.')
+ self.skipTest("Language collations are not supported.")
class Foo(Model):
field = CharField(max_length=255, db_collation=collation)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
self.isolated_local_models = [Foo]
with connection.schema_editor() as editor:
editor.create_model(Foo)
self.assertEqual(
- self.get_column_collation(Foo._meta.db_table, 'field'),
+ self.get_column_collation(Foo._meta.db_table, "field"),
collation,
)
- @isolate_apps('schema')
- @skipUnlessDBFeature('supports_collation_on_textfield')
+ @isolate_apps("schema")
+ @skipUnlessDBFeature("supports_collation_on_textfield")
def test_db_collation_textfield(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest('Language collations are not supported.')
+ self.skipTest("Language collations are not supported.")
class Foo(Model):
field = TextField(db_collation=collation)
class Meta:
- app_label = 'schema'
+ app_label = "schema"
self.isolated_local_models = [Foo]
with connection.schema_editor() as editor:
editor.create_model(Foo)
self.assertEqual(
- self.get_column_collation(Foo._meta.db_table, 'field'),
+ self.get_column_collation(Foo._meta.db_table, "field"),
collation,
)
- @skipUnlessDBFeature('supports_collation_on_charfield')
+ @skipUnlessDBFeature("supports_collation_on_charfield")
def test_add_field_db_collation(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest('Language collations are not supported.')
+ self.skipTest("Language collations are not supported.")
with connection.schema_editor() as editor:
editor.create_model(Author)
new_field = CharField(max_length=255, db_collation=collation)
- new_field.set_attributes_from_name('alias')
+ new_field.set_attributes_from_name("alias")
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
columns = self.column_classes(Author)
self.assertEqual(
- columns['alias'][0],
- connection.features.introspected_field_types['CharField'],
+ columns["alias"][0],
+ connection.features.introspected_field_types["CharField"],
)
- self.assertEqual(columns['alias'][1][8], collation)
+ self.assertEqual(columns["alias"][1][8], collation)
- @skipUnlessDBFeature('supports_collation_on_charfield')
+ @skipUnlessDBFeature("supports_collation_on_charfield")
def test_alter_field_db_collation(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest('Language collations are not supported.')
+ self.skipTest("Language collations are not supported.")
with connection.schema_editor() as editor:
editor.create_model(Author)
- old_field = Author._meta.get_field('name')
+ old_field = Author._meta.get_field("name")
new_field = CharField(max_length=255, db_collation=collation)
- new_field.set_attributes_from_name('name')
+ new_field.set_attributes_from_name("name")
new_field.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field, strict=True)
self.assertEqual(
- self.get_column_collation(Author._meta.db_table, 'name'),
+ self.get_column_collation(Author._meta.db_table, "name"),
collation,
)
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field, old_field, strict=True)
- self.assertIsNone(self.get_column_collation(Author._meta.db_table, 'name'))
+ self.assertIsNone(self.get_column_collation(Author._meta.db_table, "name"))
- @skipUnlessDBFeature('supports_collation_on_charfield')
+ @skipUnlessDBFeature("supports_collation_on_charfield")
def test_alter_field_type_and_db_collation(self):
- collation = connection.features.test_collations.get('non_default')
+ collation = connection.features.test_collations.get("non_default")
if not collation:
- self.skipTest('Language collations are not supported.')
+ self.skipTest("Language collations are not supported.")
with connection.schema_editor() as editor:
editor.create_model(Note)
- old_field = Note._meta.get_field('info')
+ old_field = Note._meta.get_field("info")
new_field = CharField(max_length=255, db_collation=collation)
- new_field.set_attributes_from_name('info')
+ new_field.set_attributes_from_name("info")
new_field.model = Note
with connection.schema_editor() as editor:
editor.alter_field(Note, old_field, new_field, strict=True)
columns = self.column_classes(Note)
self.assertEqual(
- columns['info'][0],
- connection.features.introspected_field_types['CharField'],
+ columns["info"][0],
+ connection.features.introspected_field_types["CharField"],
)
- self.assertEqual(columns['info'][1][8], collation)
+ self.assertEqual(columns["info"][1][8], collation)
with connection.schema_editor() as editor:
editor.alter_field(Note, new_field, old_field, strict=True)
columns = self.column_classes(Note)
- self.assertEqual(columns['info'][0], 'TextField')
- self.assertIsNone(columns['info'][1][8])
+ self.assertEqual(columns["info"][0], "TextField")
+ self.assertIsNone(columns["info"][1][8])
@skipUnlessDBFeature(
- 'supports_collation_on_charfield',
- 'supports_non_deterministic_collations',
+ "supports_collation_on_charfield",
+ "supports_non_deterministic_collations",
)
def test_ci_cs_db_collation(self):
- cs_collation = connection.features.test_collations.get('cs')
- ci_collation = connection.features.test_collations.get('ci')
+ cs_collation = connection.features.test_collations.get("cs")
+ ci_collation = connection.features.test_collations.get("ci")
try:
- if connection.vendor == 'mysql':
- cs_collation = 'latin1_general_cs'
- elif connection.vendor == 'postgresql':
- cs_collation = 'en-x-icu'
+ if connection.vendor == "mysql":
+ cs_collation = "latin1_general_cs"
+ elif connection.vendor == "postgresql":
+ cs_collation = "en-x-icu"
with connection.cursor() as cursor:
cursor.execute(
"CREATE COLLATION IF NOT EXISTS case_insensitive "
"(provider = icu, locale = 'und-u-ks-level2', "
"deterministic = false)"
)
- ci_collation = 'case_insensitive'
+ ci_collation = "case_insensitive"
# Create the table.
with connection.schema_editor() as editor:
editor.create_model(Author)
# Case-insensitive collation.
- old_field = Author._meta.get_field('name')
+ old_field = Author._meta.get_field("name")
new_field_ci = CharField(max_length=255, db_collation=ci_collation)
- new_field_ci.set_attributes_from_name('name')
+ new_field_ci.set_attributes_from_name("name")
new_field_ci.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, old_field, new_field_ci, strict=True)
- Author.objects.create(name='ANDREW')
- self.assertIs(Author.objects.filter(name='Andrew').exists(), True)
+ Author.objects.create(name="ANDREW")
+ self.assertIs(Author.objects.filter(name="Andrew").exists(), True)
# Case-sensitive collation.
new_field_cs = CharField(max_length=255, db_collation=cs_collation)
- new_field_cs.set_attributes_from_name('name')
+ new_field_cs.set_attributes_from_name("name")
new_field_cs.model = Author
with connection.schema_editor() as editor:
editor.alter_field(Author, new_field_ci, new_field_cs, strict=True)
- self.assertIs(Author.objects.filter(name='Andrew').exists(), False)
+ self.assertIs(Author.objects.filter(name="Andrew").exists(), False)
finally:
- if connection.vendor == 'postgresql':
+ if connection.vendor == "postgresql":
with connection.cursor() as cursor:
- cursor.execute('DROP COLLATION IF EXISTS case_insensitive')
+ cursor.execute("DROP COLLATION IF EXISTS case_insensitive")