mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #34760 -- Dropped support for SQLite < 3.27.
This commit is contained in:
parent
f46a6b2816
commit
2b582387d5
@ -134,9 +134,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
|
||||
else:
|
||||
super().remove_field(model, field)
|
||||
|
||||
def alter_db_table(
|
||||
self, model, old_db_table, new_db_table, disable_constraints=True
|
||||
):
|
||||
def alter_db_table(self, model, old_db_table, new_db_table):
|
||||
from django.contrib.gis.db.models import GeometryField
|
||||
|
||||
if old_db_table == new_db_table or (
|
||||
@ -155,7 +153,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
|
||||
}
|
||||
)
|
||||
# Alter table
|
||||
super().alter_db_table(model, old_db_table, new_db_table, disable_constraints)
|
||||
super().alter_db_table(model, old_db_table, new_db_table)
|
||||
# Repoint any straggler names
|
||||
for geom_table in self.geometry_tables:
|
||||
try:
|
||||
|
@ -174,9 +174,6 @@ class BaseDatabaseFeatures:
|
||||
|
||||
schema_editor_uses_clientside_param_binding = False
|
||||
|
||||
# Does it support operations requiring references rename in a transaction?
|
||||
supports_atomic_references_rename = True
|
||||
|
||||
# Can we issue more than one ALTER COLUMN clause in an ALTER TABLE?
|
||||
supports_combined_alters = False
|
||||
|
||||
|
@ -182,7 +182,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
|
||||
conn.execute("PRAGMA foreign_keys = ON")
|
||||
# The macOS bundled SQLite defaults legacy_alter_table ON, which
|
||||
# prevents atomic table renames (feature supports_atomic_references_rename)
|
||||
# prevents atomic table renames.
|
||||
conn.execute("PRAGMA legacy_alter_table = OFF")
|
||||
return conn
|
||||
|
||||
|
@ -9,7 +9,7 @@ from .base import Database
|
||||
|
||||
|
||||
class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
minimum_database_version = (3, 21)
|
||||
minimum_database_version = (3, 27)
|
||||
test_db_allows_multiple_connections = False
|
||||
supports_unspecified_pk = True
|
||||
supports_timezones = False
|
||||
@ -26,13 +26,11 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
time_cast_precision = 3
|
||||
can_release_savepoints = True
|
||||
has_case_insensitive_like = True
|
||||
# Is "ALTER TABLE ... RENAME COLUMN" supported?
|
||||
can_alter_table_rename_column = Database.sqlite_version_info >= (3, 25, 0)
|
||||
# Is "ALTER TABLE ... DROP COLUMN" supported?
|
||||
can_alter_table_drop_column = Database.sqlite_version_info >= (3, 35, 5)
|
||||
supports_parentheses_in_compound = False
|
||||
can_defer_constraint_checks = True
|
||||
supports_over_clause = Database.sqlite_version_info >= (3, 25, 0)
|
||||
supports_over_clause = True
|
||||
supports_frame_range_fixed_distance = Database.sqlite_version_info >= (3, 28, 0)
|
||||
supports_aggregate_filter_clause = Database.sqlite_version_info >= (3, 30, 1)
|
||||
supports_order_by_nulls_modifier = Database.sqlite_version_info >= (3, 30, 0)
|
||||
@ -40,8 +38,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
requires_compound_order_by_subquery = Database.sqlite_version_info < (3, 30)
|
||||
order_by_nulls_first = True
|
||||
supports_json_field_contains = False
|
||||
supports_update_conflicts = Database.sqlite_version_info >= (3, 24, 0)
|
||||
supports_update_conflicts_with_target = supports_update_conflicts
|
||||
supports_update_conflicts = True
|
||||
supports_update_conflicts_with_target = True
|
||||
test_collations = {
|
||||
"ci": "nocase",
|
||||
"cs": "binary",
|
||||
@ -88,15 +86,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
"test_integer_with_negative_precision",
|
||||
},
|
||||
}
|
||||
if Database.sqlite_version_info < (3, 27):
|
||||
skips.update(
|
||||
{
|
||||
"Nondeterministic failure on SQLite < 3.27.": {
|
||||
"expressions_window.tests.WindowFunctionTests."
|
||||
"test_subquery_row_range_rank",
|
||||
},
|
||||
}
|
||||
)
|
||||
if self.connection.is_in_memory_db():
|
||||
skips.update(
|
||||
{
|
||||
@ -131,10 +120,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
)
|
||||
return skips
|
||||
|
||||
@cached_property
|
||||
def supports_atomic_references_rename(self):
|
||||
return Database.sqlite_version_info >= (3, 26, 0)
|
||||
|
||||
@cached_property
|
||||
def introspected_field_types(self):
|
||||
return {
|
||||
|
@ -7,7 +7,6 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
from django.db.backends.ddl_references import Statement
|
||||
from django.db.backends.utils import strip_quotes
|
||||
from django.db.models import NOT_PROVIDED, UniqueConstraint
|
||||
from django.db.transaction import atomic
|
||||
|
||||
|
||||
class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||
@ -73,105 +72,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||
def prepare_default(self, value):
|
||||
return self.quote_value(value)
|
||||
|
||||
def _is_referenced_by_fk_constraint(
|
||||
self, table_name, column_name=None, ignore_self=False
|
||||
):
|
||||
"""
|
||||
Return whether or not the provided table name is referenced by another
|
||||
one. If `column_name` is specified, only references pointing to that
|
||||
column are considered. If `ignore_self` is True, self-referential
|
||||
constraints are ignored.
|
||||
"""
|
||||
with self.connection.cursor() as cursor:
|
||||
for other_table in self.connection.introspection.get_table_list(cursor):
|
||||
if ignore_self and other_table.name == table_name:
|
||||
continue
|
||||
relations = self.connection.introspection.get_relations(
|
||||
cursor, other_table.name
|
||||
)
|
||||
for constraint_column, constraint_table in relations.values():
|
||||
if constraint_table == table_name and (
|
||||
column_name is None or constraint_column == column_name
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def alter_db_table(
|
||||
self, model, old_db_table, new_db_table, disable_constraints=True
|
||||
):
|
||||
if (
|
||||
not self.connection.features.supports_atomic_references_rename
|
||||
and disable_constraints
|
||||
and self._is_referenced_by_fk_constraint(old_db_table)
|
||||
):
|
||||
if self.connection.in_atomic_block:
|
||||
raise NotSupportedError(
|
||||
(
|
||||
"Renaming the %r table while in a transaction is not "
|
||||
"supported on SQLite < 3.26 because it would break referential "
|
||||
"integrity. Try adding `atomic = False` to the Migration class."
|
||||
)
|
||||
% old_db_table
|
||||
)
|
||||
self.connection.enable_constraint_checking()
|
||||
super().alter_db_table(model, old_db_table, new_db_table)
|
||||
self.connection.disable_constraint_checking()
|
||||
else:
|
||||
super().alter_db_table(model, old_db_table, new_db_table)
|
||||
|
||||
def alter_field(self, model, old_field, new_field, strict=False):
|
||||
if not self._field_should_be_altered(old_field, new_field):
|
||||
return
|
||||
old_field_name = old_field.name
|
||||
table_name = model._meta.db_table
|
||||
_, old_column_name = old_field.get_attname_column()
|
||||
if (
|
||||
new_field.name != old_field_name
|
||||
and not self.connection.features.supports_atomic_references_rename
|
||||
and self._is_referenced_by_fk_constraint(
|
||||
table_name, old_column_name, ignore_self=True
|
||||
)
|
||||
):
|
||||
if self.connection.in_atomic_block:
|
||||
raise NotSupportedError(
|
||||
(
|
||||
"Renaming the %r.%r column while in a transaction is not "
|
||||
"supported on SQLite < 3.26 because it would break referential "
|
||||
"integrity. Try adding `atomic = False` to the Migration class."
|
||||
)
|
||||
% (model._meta.db_table, old_field_name)
|
||||
)
|
||||
with atomic(self.connection.alias):
|
||||
super().alter_field(model, old_field, new_field, strict=strict)
|
||||
# Follow SQLite's documented procedure for performing changes
|
||||
# that don't affect the on-disk content.
|
||||
# https://sqlite.org/lang_altertable.html#otheralter
|
||||
with self.connection.cursor() as cursor:
|
||||
schema_version = cursor.execute("PRAGMA schema_version").fetchone()[
|
||||
0
|
||||
]
|
||||
cursor.execute("PRAGMA writable_schema = 1")
|
||||
references_template = ' REFERENCES "%s" ("%%s") ' % table_name
|
||||
new_column_name = new_field.get_attname_column()[1]
|
||||
search = references_template % old_column_name
|
||||
replacement = references_template % new_column_name
|
||||
cursor.execute(
|
||||
"UPDATE sqlite_master SET sql = replace(sql, %s, %s)",
|
||||
(search, replacement),
|
||||
)
|
||||
cursor.execute("PRAGMA schema_version = %d" % (schema_version + 1))
|
||||
cursor.execute("PRAGMA writable_schema = 0")
|
||||
# The integrity check will raise an exception and rollback
|
||||
# the transaction if the sqlite_master updates corrupt the
|
||||
# database.
|
||||
cursor.execute("PRAGMA integrity_check")
|
||||
# Perform a VACUUM to refresh the database representation from
|
||||
# the sqlite_master table.
|
||||
with self.connection.cursor() as cursor:
|
||||
cursor.execute("VACUUM")
|
||||
else:
|
||||
super().alter_field(model, old_field, new_field, strict=strict)
|
||||
|
||||
def _remake_table(
|
||||
self, model, create_field=None, delete_field=None, alter_fields=None
|
||||
):
|
||||
@ -358,7 +258,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||
new_model,
|
||||
new_model._meta.db_table,
|
||||
model._meta.db_table,
|
||||
disable_constraints=False,
|
||||
)
|
||||
|
||||
# Run deferred SQL on correct table
|
||||
@ -458,8 +357,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||
# Use "ALTER TABLE ... RENAME COLUMN" if only the column name
|
||||
# changed and there aren't any constraints.
|
||||
if (
|
||||
self.connection.features.can_alter_table_rename_column
|
||||
and old_field.column != new_field.column
|
||||
old_field.column != new_field.column
|
||||
and self.column_sql(model, old_field) == self.column_sql(model, new_field)
|
||||
and not (
|
||||
old_field.remote_field
|
||||
|
@ -59,7 +59,7 @@ Database Library Requirements Supported Versions Notes
|
||||
PostgreSQL GEOS, GDAL, PROJ, PostGIS 12+ Requires PostGIS.
|
||||
MySQL GEOS, GDAL 8.0.11+ :ref:`Limited functionality <mysql-spatial-limitations>`.
|
||||
Oracle GEOS, GDAL 19+ XE not supported.
|
||||
SQLite GEOS, GDAL, PROJ, SpatiaLite 3.21.0+ Requires SpatiaLite 4.3+
|
||||
SQLite GEOS, GDAL, PROJ, SpatiaLite 3.27.0+ Requires SpatiaLite 4.3+
|
||||
================== ============================== ================== =========================================
|
||||
|
||||
See also `this comparison matrix`__ on the OSGeo Wiki for
|
||||
|
@ -792,7 +792,7 @@ appropriate typecasting.
|
||||
SQLite notes
|
||||
============
|
||||
|
||||
Django supports SQLite 3.21.0 and later.
|
||||
Django supports SQLite 3.27.0 and later.
|
||||
|
||||
SQLite_ provides an excellent development alternative for applications that
|
||||
are predominantly read-only or require a smaller installation footprint. As
|
||||
|
@ -2411,7 +2411,7 @@ On databases that support it (all but Oracle), setting the ``ignore_conflicts``
|
||||
parameter to ``True`` tells the database to ignore failure to insert any rows
|
||||
that fail constraints such as duplicate unique values.
|
||||
|
||||
On databases that support it (all except Oracle and SQLite < 3.24), setting the
|
||||
On databases that support it (all except Oracle), setting the
|
||||
``update_conflicts`` parameter to ``True``, tells the database to update
|
||||
``update_fields`` when a row insertion fails on conflicts. On PostgreSQL and
|
||||
SQLite, in addition to ``update_fields``, a list of ``unique_fields`` that may
|
||||
|
@ -566,6 +566,8 @@ Miscellaneous
|
||||
* The ``AlreadyRegistered`` and ``NotRegistered`` exceptions are moved from
|
||||
``django.contrib.admin.sites`` to ``django.contrib.admin.exceptions``.
|
||||
|
||||
* The minimum supported version of SQLite is increased from 3.21.0 to 3.27.0.
|
||||
|
||||
.. _deprecated-features-5.0:
|
||||
|
||||
Features deprecated in 5.0
|
||||
|
@ -7,17 +7,12 @@ from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
from django.db import NotSupportedError, connection, transaction
|
||||
from django.db.models import Aggregate, Avg, CharField, StdDev, Sum, Variance
|
||||
from django.db.models import Aggregate, Avg, StdDev, Sum, Variance
|
||||
from django.db.utils import ConnectionHandler
|
||||
from django.test import (
|
||||
TestCase,
|
||||
TransactionTestCase,
|
||||
override_settings,
|
||||
skipIfDBFeature,
|
||||
)
|
||||
from django.test import TestCase, TransactionTestCase, override_settings
|
||||
from django.test.utils import isolate_apps
|
||||
|
||||
from ..models import Author, Item, Object, Square
|
||||
from ..models import Item, Object, Square
|
||||
|
||||
|
||||
@unittest.skipUnless(connection.vendor == "sqlite", "SQLite tests")
|
||||
@ -106,9 +101,9 @@ class Tests(TestCase):
|
||||
connections["default"].close()
|
||||
self.assertTrue(os.path.isfile(os.path.join(tmp, "test.db")))
|
||||
|
||||
@mock.patch.object(connection, "get_database_version", return_value=(3, 20))
|
||||
@mock.patch.object(connection, "get_database_version", return_value=(3, 26))
|
||||
def test_check_database_version_supported(self, mocked_get_database_version):
|
||||
msg = "SQLite 3.21 or later is required (found 3.20)."
|
||||
msg = "SQLite 3.27 or later is required (found 3.26)."
|
||||
with self.assertRaisesMessage(NotSupportedError, msg):
|
||||
connection.check_database_version_supported()
|
||||
self.assertTrue(mocked_get_database_version.called)
|
||||
@ -167,39 +162,6 @@ class SchemaTests(TransactionTestCase):
|
||||
self.assertFalse(constraint_checks_enabled())
|
||||
self.assertTrue(constraint_checks_enabled())
|
||||
|
||||
@skipIfDBFeature("supports_atomic_references_rename")
|
||||
def test_field_rename_inside_atomic_block(self):
|
||||
"""
|
||||
NotImplementedError is raised when a model field rename is attempted
|
||||
inside an atomic block.
|
||||
"""
|
||||
new_field = CharField(max_length=255, unique=True)
|
||||
new_field.set_attributes_from_name("renamed")
|
||||
msg = (
|
||||
"Renaming the 'backends_author'.'name' column while in a "
|
||||
"transaction is not supported on SQLite < 3.26 because it would "
|
||||
"break referential integrity. Try adding `atomic = False` to the "
|
||||
"Migration class."
|
||||
)
|
||||
with self.assertRaisesMessage(NotSupportedError, msg):
|
||||
with connection.schema_editor(atomic=True) as editor:
|
||||
editor.alter_field(Author, Author._meta.get_field("name"), new_field)
|
||||
|
||||
@skipIfDBFeature("supports_atomic_references_rename")
|
||||
def test_table_rename_inside_atomic_block(self):
|
||||
"""
|
||||
NotImplementedError is raised when a table rename is attempted inside
|
||||
an atomic block.
|
||||
"""
|
||||
msg = (
|
||||
"Renaming the 'backends_author' table while in a transaction is "
|
||||
"not supported on SQLite < 3.26 because it would break referential "
|
||||
"integrity. Try adding `atomic = False` to the Migration class."
|
||||
)
|
||||
with self.assertRaisesMessage(NotSupportedError, msg):
|
||||
with connection.schema_editor(atomic=True) as editor:
|
||||
editor.alter_db_table(Author, "backends_author", "renamed_table")
|
||||
|
||||
|
||||
@unittest.skipUnless(connection.vendor == "sqlite", "Test only for SQLite")
|
||||
@override_settings(DEBUG=True)
|
||||
|
@ -805,10 +805,7 @@ class OperationTests(OperationTestBase):
|
||||
)
|
||||
# Migrate forwards
|
||||
new_state = project_state.clone()
|
||||
atomic_rename = connection.features.supports_atomic_references_rename
|
||||
new_state = self.apply_operations(
|
||||
"test_rnmo", new_state, [operation], atomic=atomic_rename
|
||||
)
|
||||
new_state = self.apply_operations("test_rnmo", new_state, [operation])
|
||||
# Test new state and database
|
||||
self.assertNotIn(("test_rnmo", "pony"), new_state.models)
|
||||
self.assertIn(("test_rnmo", "horse"), new_state.models)
|
||||
@ -828,7 +825,7 @@ class OperationTests(OperationTestBase):
|
||||
)
|
||||
# Migrate backwards
|
||||
original_state = self.unapply_operations(
|
||||
"test_rnmo", project_state, [operation], atomic=atomic_rename
|
||||
"test_rnmo", project_state, [operation]
|
||||
)
|
||||
# Test original state and database
|
||||
self.assertIn(("test_rnmo", "pony"), original_state.models)
|
||||
@ -907,8 +904,7 @@ class OperationTests(OperationTestBase):
|
||||
self.assertFKNotExists(
|
||||
"test_rmwsrf_rider", ["friend_id"], ("test_rmwsrf_horserider", "id")
|
||||
)
|
||||
atomic_rename = connection.features.supports_atomic_references_rename
|
||||
with connection.schema_editor(atomic=atomic_rename) as editor:
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards("test_rmwsrf", editor, project_state, new_state)
|
||||
self.assertTableNotExists("test_rmwsrf_rider")
|
||||
self.assertTableExists("test_rmwsrf_horserider")
|
||||
@ -922,7 +918,7 @@ class OperationTests(OperationTestBase):
|
||||
("test_rmwsrf_horserider", "id"),
|
||||
)
|
||||
# And test reversal
|
||||
with connection.schema_editor(atomic=atomic_rename) as editor:
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards(
|
||||
"test_rmwsrf", editor, new_state, project_state
|
||||
)
|
||||
@ -972,9 +968,7 @@ class OperationTests(OperationTestBase):
|
||||
self.assertFKNotExists(
|
||||
"test_rmwsc_rider", ["pony_id"], ("test_rmwsc_shetlandpony", "id")
|
||||
)
|
||||
with connection.schema_editor(
|
||||
atomic=connection.features.supports_atomic_references_rename
|
||||
) as editor:
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards("test_rmwsc", editor, project_state, new_state)
|
||||
# Now we have a little horse table, not shetland pony
|
||||
self.assertTableNotExists("test_rmwsc_shetlandpony")
|
||||
@ -1031,7 +1025,6 @@ class OperationTests(OperationTestBase):
|
||||
operations=[
|
||||
migrations.RenameModel("ReflexivePony", "ReflexivePony2"),
|
||||
],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
Pony = project_state.apps.get_model(app_label, "ReflexivePony2")
|
||||
pony = Pony.objects.create()
|
||||
@ -1070,7 +1063,6 @@ class OperationTests(OperationTestBase):
|
||||
operations=[
|
||||
migrations.RenameModel("Pony", "Pony2"),
|
||||
],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
Pony = project_state.apps.get_model(app_label, "Pony2")
|
||||
Rider = project_state.apps.get_model(app_label, "Rider")
|
||||
@ -1125,7 +1117,6 @@ class OperationTests(OperationTestBase):
|
||||
app_label_2,
|
||||
project_state,
|
||||
operations=[migrations.RenameModel("Rider", "Pony")],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
|
||||
m2m_table = f"{app_label_2}_pony_riders"
|
||||
@ -1146,7 +1137,6 @@ class OperationTests(OperationTestBase):
|
||||
app_label_2,
|
||||
project_state_2,
|
||||
operations=[migrations.RenameModel("Rider", "Pony")],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
m2m_table = f"{app_label_2}_rider_riders"
|
||||
self.assertColumnExists(m2m_table, "to_rider_id")
|
||||
@ -1178,7 +1168,6 @@ class OperationTests(OperationTestBase):
|
||||
app_label,
|
||||
project_state,
|
||||
operations=[migrations.RenameModel("Pony", "PinkPony")],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
Pony = new_state.apps.get_model(app_label, "PinkPony")
|
||||
Rider = new_state.apps.get_model(app_label, "Rider")
|
||||
@ -1219,7 +1208,6 @@ class OperationTests(OperationTestBase):
|
||||
operations=[
|
||||
migrations.RenameModel("Rider", "Rider2"),
|
||||
],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
Pony = project_state.apps.get_model(app_label, "Pony")
|
||||
Rider = project_state.apps.get_model(app_label, "Rider2")
|
||||
@ -1341,7 +1329,6 @@ class OperationTests(OperationTestBase):
|
||||
),
|
||||
migrations.RenameModel(old_name="Rider", new_name="Jockey"),
|
||||
],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
Pony = project_state.apps.get_model(app_label, "Pony")
|
||||
Jockey = project_state.apps.get_model(app_label, "Jockey")
|
||||
@ -2042,13 +2029,12 @@ class OperationTests(OperationTestBase):
|
||||
second_state = first_state.clone()
|
||||
operation = migrations.AlterModelTable(name="pony", table=None)
|
||||
operation.state_forwards(app_label, second_state)
|
||||
atomic_rename = connection.features.supports_atomic_references_rename
|
||||
with connection.schema_editor(atomic=atomic_rename) as editor:
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards(app_label, editor, first_state, second_state)
|
||||
self.assertTableExists(new_m2m_table)
|
||||
self.assertTableNotExists(original_m2m_table)
|
||||
# And test reversal
|
||||
with connection.schema_editor(atomic=atomic_rename) as editor:
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards(app_label, editor, second_state, first_state)
|
||||
self.assertTableExists(original_m2m_table)
|
||||
self.assertTableNotExists(new_m2m_table)
|
||||
@ -2988,7 +2974,6 @@ class OperationTests(OperationTestBase):
|
||||
"Pony", "id", models.CharField(primary_key=True, max_length=99)
|
||||
),
|
||||
],
|
||||
atomic=connection.features.supports_atomic_references_rename,
|
||||
)
|
||||
|
||||
def test_rename_field(self):
|
||||
|
@ -2075,9 +2075,7 @@ class SchemaTests(TransactionTestCase):
|
||||
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:
|
||||
with connection.schema_editor() 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")
|
||||
@ -2122,9 +2120,7 @@ class SchemaTests(TransactionTestCase):
|
||||
new_field = IntegerField(db_default=1985)
|
||||
new_field.set_attributes_from_name("renamed_year")
|
||||
new_field.model = AuthorDbDefault
|
||||
with connection.schema_editor(
|
||||
atomic=connection.features.supports_atomic_references_rename
|
||||
) as editor:
|
||||
with connection.schema_editor() as editor:
|
||||
editor.alter_field(AuthorDbDefault, old_field, new_field, strict=True)
|
||||
columns = self.column_classes(AuthorDbDefault)
|
||||
self.assertEqual(columns["renamed_year"][1].default, "1985")
|
||||
@ -3550,9 +3546,7 @@ class SchemaTests(TransactionTestCase):
|
||||
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() as editor:
|
||||
editor.alter_db_table(Author, "schema_author", "schema_otherauthor")
|
||||
Author._meta.db_table = "schema_otherauthor"
|
||||
columns = self.column_classes(Author)
|
||||
@ -3563,9 +3557,7 @@ class SchemaTests(TransactionTestCase):
|
||||
# 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() as editor:
|
||||
editor.alter_db_table(Author, "schema_otherauthor", "schema_author")
|
||||
# Ensure the table is still there
|
||||
Author._meta.db_table = "schema_author"
|
||||
@ -5130,8 +5122,7 @@ class SchemaTests(TransactionTestCase):
|
||||
editor.add_field(Book, author)
|
||||
|
||||
def test_rename_table_renames_deferred_sql_references(self):
|
||||
atomic_rename = connection.features.supports_atomic_references_rename
|
||||
with connection.schema_editor(atomic=atomic_rename) as editor:
|
||||
with connection.schema_editor() as editor:
|
||||
editor.create_model(Author)
|
||||
editor.create_model(Book)
|
||||
editor.alter_db_table(Author, "schema_author", "schema_renamed_author")
|
||||
|
Loading…
Reference in New Issue
Block a user