Fixed #33057 -- Fixed recreation of foreign key constraints in m2m tables when altering type of referenced primary key on Oracle.
This commit is contained in:
parent
b667ac24ea
commit
1eb3f500a4
|
@ -3,7 +3,9 @@ import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.db import DatabaseError
|
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):
|
class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
|
@ -124,6 +126,17 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
||||||
self.remove_field(model, old_field)
|
self.remove_field(model, old_field)
|
||||||
# Rename and possibly make the new field NOT NULL
|
# Rename and possibly make the new field NOT NULL
|
||||||
super().alter_field(model, new_temp_field, new_field)
|
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):
|
def _alter_column_type_sql(self, model, old_field, new_field, new_type):
|
||||||
auto_field_types = {'AutoField', 'BigAutoField', 'SmallAutoField'}
|
auto_field_types = {'AutoField', 'BigAutoField', 'SmallAutoField'}
|
||||||
|
|
|
@ -1500,10 +1500,32 @@ class OperationTests(OperationTestBase):
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor:
|
||||||
operation.database_forwards("test_alflpkfk", editor, project_state, new_state)
|
operation.database_forwards("test_alflpkfk", editor, project_state, new_state)
|
||||||
assertIdTypeEqualsFkType()
|
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
|
# And test reversal
|
||||||
with connection.schema_editor() as editor:
|
with connection.schema_editor() as editor:
|
||||||
operation.database_backwards("test_alflpkfk", editor, new_state, project_state)
|
operation.database_backwards("test_alflpkfk", editor, new_state, project_state)
|
||||||
assertIdTypeEqualsFkType()
|
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):
|
def test_alter_field_pk_mti_fk(self):
|
||||||
app_label = 'test_alflpkmtifk'
|
app_label = 'test_alflpkmtifk'
|
||||||
|
|
Loading…
Reference in New Issue