我有一个Django模型,它有另一个模型的外键:
class Example(models.Model)
something = models.ForeignKey(SomeModel, db_index=True)
我希望将基础数据库列保留为字段,但要删除数据库中的外键约束。
因此模型将变为:
class Example(models.Model):
something_id = models.IntegerField()
而且,要清楚,something_id
是Django为外键字段创建的列。
我不想删除列并重新创建它(这是Django在更改模型后自动生成迁移时所执行的操作)。
我想保留字段但是我想通过迁移删除数据库中的外键约束。我不清楚如何使用Django迁移实现这一点 - 是否有一些内置支持或者我必须运行一些原始SQL,如果是这样,我如何以编程方式获取约束的名称?
答案 0 :(得分:10)
这就是我设法做到的,它是基于nimasmi的答案:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
# These *WILL* impact the database!
database_operations = [
migrations.AlterField(
model_name='Example',
name='something',
field=models.ForeignKey('Something', db_constraint=False, db_index=True, null=False)
),
]
# These *WON'T* impact the database, they update Django state *ONLY*!
state_operations = [
migrations.AlterField(
model_name='Example',
name='something',
field=models.IntegerField(db_index=True, null=False)
),
migrations.RenameField(
model_name='Example',
old_name='something',
new_name='something_id'
),
]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=database_operations,
state_operations=state_operations
)
]
答案 1 :(得分:6)
See SeparateDatabaseAndState. It allows you to specify a Django (state) part of the migration separately from the database part of the migration.
Create the migration, as normal. You will end up with something like:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_whatever.py'),
]
operations = [
migrations.AlterField(
model_name='example',
name='something',
field=models.CharField(max_length=255, null=True)),
),
]
Now manually amend this to:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_whatever.py'),
]
state_operations = [
migrations.AlterField(
model_name='example',
name='something',
field=models.CharField(max_length=255, null=True)),
),
]
operations = [
migrations.SeparateDatabaseAndState(state_operations=state_operations)
]
Note that you are not specifying any database_operations
argument, so the Django relationships are amended, but the database data is unchanged.
Needless to say: take a backup before you try this.
答案 2 :(得分:2)
从Django 2.0开始,将您的字段更改为models.ForeignKey(db_constraint=False, db_index=False, ...)
将生成一个迁移,该迁移可以执行ALTER TABLE DROP CONSTRAINT和DROP INDEX IF EXISTS,这正是您想要的。