summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2021-08-31 13:43:10 +0200
committerGitHub <noreply@github.com>2021-08-31 13:43:10 +0200
commit1eb3f500a44b08a05868cd8bd85501dd6c7ee6c7 (patch)
treedaf8147744385334dc490ff6f9e74495f521108f
parentb667ac24ead73300c49e265201b6c0b913ee36a3 (diff)
Fixed #33057 -- Fixed recreation of foreign key constraints in m2m tables when altering type of referenced primary key on Oracle.
-rw-r--r--django/db/backends/oracle/schema.py15
-rw-r--r--tests/migrations/test_operations.py22
2 files changed, 36 insertions, 1 deletions
diff --git a/django/db/backends/oracle/schema.py b/django/db/backends/oracle/schema.py
index cf875fc5e3..0d1c7f5d4b 100644
--- a/django/db/backends/oracle/schema.py
+++ b/django/db/backends/oracle/schema.py
@@ -3,7 +3,9 @@ import datetime
import re
from django.db import DatabaseError
-from django.db.backends.base.schema import BaseDatabaseSchemaEditor
+from django.db.backends.base.schema import (
+ BaseDatabaseSchemaEditor, _related_non_m2m_objects,
+)
class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
@@ -124,6 +126,17 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
self.remove_field(model, old_field)
# Rename and possibly make the new field NOT NULL
super().alter_field(model, new_temp_field, new_field)
+ # Recreate foreign key (if necessary) because the old field is not
+ # passed to the alter_field() and data types of new_temp_field and
+ # new_field always match.
+ new_type = new_field.db_type(self.connection)
+ if (
+ (old_field.primary_key and new_field.primary_key) or
+ (old_field.unique and new_field.unique)
+ ) and old_type != new_type:
+ for _, rel in _related_non_m2m_objects(new_temp_field, new_field):
+ if rel.field.db_constraint:
+ self.execute(self._create_fk_sql(rel.related_model, rel.field, '_fk'))
def _alter_column_type_sql(self, model, old_field, new_field, new_type):
auto_field_types = {'AutoField', 'BigAutoField', 'SmallAutoField'}
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 6d016a2a25..5ae75a477b 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -1500,10 +1500,32 @@ class OperationTests(OperationTestBase):
with connection.schema_editor() as editor:
operation.database_forwards("test_alflpkfk", editor, project_state, new_state)
assertIdTypeEqualsFkType()
+ if connection.features.supports_foreign_keys:
+ self.assertFKExists(
+ 'test_alflpkfk_pony_stables',
+ ['pony_id'],
+ ('test_alflpkfk_pony', 'id'),
+ )
+ self.assertFKExists(
+ 'test_alflpkfk_stable_ponies',
+ ['pony_id'],
+ ('test_alflpkfk_pony', 'id'),
+ )
# And test reversal
with connection.schema_editor() as editor:
operation.database_backwards("test_alflpkfk", editor, new_state, project_state)
assertIdTypeEqualsFkType()
+ if connection.features.supports_foreign_keys:
+ self.assertFKExists(
+ 'test_alflpkfk_pony_stables',
+ ['pony_id'],
+ ('test_alflpkfk_pony', 'id'),
+ )
+ self.assertFKExists(
+ 'test_alflpkfk_stable_ponies',
+ ['pony_id'],
+ ('test_alflpkfk_pony', 'id'),
+ )
def test_alter_field_pk_mti_fk(self):
app_label = 'test_alflpkmtifk'