Opened 11 years ago
Last modified 10 years ago
#24653 closed Bug
Migrations: Removing a field with foreign key constraint fails — at Version 3
| Reported by: | László Károlyi | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 1.9 |
| Severity: | Normal | Keywords: | foreign key constraint mysql |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Hey,
I have a model that has a foreign key to another model. Let's say I change my mind and want the relation the other way around (the another model having a foreign key to my model), and so I modify the models accordingly, removing the foreign key of my model.
This creates a migration with a migrations.RemoveField on the model, which is just right. But when running this migration on MySQL, I get an error saying
django.db.utils.OperationalError: (1553, "Cannot drop index 'base_comment_f6be1d8d': needed in a foreign key constraint")
and the migration fails.
Shouldn't the migrations.RemoveField drop that constraint automatically?
This happens using python 3, might have to do something with #24390.
The only way to workaround this now is to create a migrations.RunPython(remove_fk) statement before the migrations.RemoveField, to remove the foreign key manually, by getting its name from INFORMATION_SCHEMA:
def remove_fk(apps, schema_editor):
from django.db.backends.mysql.base import DatabaseWrapper
if isinstance(schema_editor.connection, DatabaseWrapper):
cursor = schema_editor.connection.cursor()
Edit = apps.get_model('base', 'Edit')
table_edit_name = Edit._meta.db_table
cursor.execute('SELECT DATABASE()')
db_name = cursor.fetchall()[0][0]
cursor.execute(
'SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE'
' `TABLE_SCHEMA`=\'%s\' AND `REFERENCED_TABLE_NAME`=\'%s\'' % (
db_name,
table_edit_name
))
result = cursor.fetchall()
if not result:
return
Comment = apps.get_model('base', 'Comment')
table_comment_name = Comment._meta.db_table
fk_name = result[0][0]
query = 'ALTER TABLE `%s` DROP FOREIGN KEY `%s`' % (
table_comment_name,
fk_name
)
cursor.execute(query)
Change History (3)
comment:1 by , 11 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 11 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 11 years ago
| Description: | modified (diff) |
|---|