summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2020-04-17 00:54:37 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-04-21 08:37:47 +0200
commit5220ca8d8a109721378e8d4c7f32e342c3a83af6 (patch)
tree07324cd54be61dc5a8cdbdf39801ee71591bc61a
parenta54828085732d5d2f020c2fb52fe1cbe1a20a6c9 (diff)
Refs #30591 -- Adjusted table rebuild for non-pk relationship on SQLite.
The existing code was only accounting for primary key changes and not all unique key fields that can be referenced.
-rw-r--r--django/db/backends/sqlite3/schema.py22
-rw-r--r--tests/migrations/test_operations.py14
2 files changed, 25 insertions, 11 deletions
diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py
index 78d88c7dd9..aca5d61b39 100644
--- a/django/db/backends/sqlite3/schema.py
+++ b/django/db/backends/sqlite3/schema.py
@@ -358,8 +358,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
return self.execute(self._rename_field_sql(model._meta.db_table, old_field, new_field, new_type))
# Alter by remaking table
self._remake_table(model, alter_field=(old_field, new_field))
- # Rebuild tables with FKs pointing to this field if the PK type changed.
- if old_field.primary_key and new_field.primary_key and old_type != new_type:
+ # Rebuild tables with FKs pointing to this field.
+ if new_field.unique and old_type != new_type:
related_models = set()
opts = new_field.model._meta
for remote_field in opts.related_objects:
@@ -367,15 +367,17 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
if remote_field.related_model == model:
continue
if not remote_field.many_to_many:
- related_models.add(remote_field.related_model)
- elif remote_field.through._meta.auto_created:
+ if remote_field.field_name == new_field.name:
+ related_models.add(remote_field.related_model)
+ elif new_field.primary_key and remote_field.through._meta.auto_created:
related_models.add(remote_field.through)
- for many_to_many in opts.many_to_many:
- # Ignore self-relationship since the table was already rebuilt.
- if many_to_many.related_model == model:
- continue
- if many_to_many.remote_field.through._meta.auto_created:
- related_models.add(many_to_many.remote_field.through)
+ if new_field.primary_key:
+ for many_to_many in opts.many_to_many:
+ # Ignore self-relationship since the table was already rebuilt.
+ if many_to_many.related_model == model:
+ continue
+ if many_to_many.remote_field.through._meta.auto_created:
+ related_models.add(many_to_many.remote_field.through)
for related_model in related_models:
self._remake_table(related_model)
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 051b8036b5..bb4b74e727 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -1341,7 +1341,7 @@ class OperationTests(OperationTestBase):
project_state = self.apply_operations(app_label, ProjectState(), operations=[
migrations.CreateModel('Rider', fields=[
('id', models.AutoField(primary_key=True)),
- ('code', models.PositiveIntegerField(unique=True)),
+ ('code', models.IntegerField(unique=True)),
]),
migrations.CreateModel('Pony', fields=[
('id', models.AutoField(primary_key=True)),
@@ -1354,6 +1354,18 @@ class OperationTests(OperationTestBase):
models.CharField(max_length=100, unique=True),
)
self.apply_operations(app_label, project_state, operations=[operation])
+ id_type, id_null = [
+ (c.type_code, c.null_ok)
+ for c in self.get_table_description('%s_rider' % app_label)
+ if c.name == 'code'
+ ][0]
+ fk_type, fk_null = [
+ (c.type_code, c.null_ok)
+ for c in self.get_table_description('%s_pony' % app_label)
+ if c.name == 'rider_id'
+ ][0]
+ self.assertEqual(id_type, fk_type)
+ self.assertEqual(id_null, fk_null)
@skipUnlessDBFeature('supports_foreign_keys')
def test_alter_field_reloads_state_on_fk_with_to_field_related_name_target_type_change(self):