Django 1.11 引入了基于类的模型索引。之前定义为
class A(models.Model):
class Meta:
index_together = [
('foo', 'bar'),
]
现在可以定义为
class A(models.Model):
class Meta:
indexes = [
models.Index(fields=['foo', 'bar']),
]
当我更改为模型运行的新语法时
python manage.py makemigrations
,它将创建类似的迁移
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.AlterIndexTogether(
name='a',
index_together=set([]),
),
migrations.AddIndex(
model_name='a',
index=models.Index(fields=['foo', 'bar'], name='app_a_f12345_idx'),
),
]
此迁移将删除并重新创建我的索引,这是我想避免的事情。
从旧语法切换到新语法的推荐方法是什么?我在文档中找不到任何内容。
您可以编辑生成的迁移,使索引
name
与原始 index_together
索引名称匹配,然后使用 manage.py migrate
选项运行 --fake
。
而不是
--fake
,我想使用一些会自动应用于各种数据库的东西,仅用于此特定迁移。因此,我最终使用了 AddIndex
、RemoveIndex
、RenameIndex
和 SeparateDatabaseAndState
的组合,因为 Django 将我在上游修改的这个索引视为新索引。
# Generated by Django 4.2.18
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("app_name", "00XX_auto_XXXX"),
]
operations = [
# Handle this operation a bit differently since old migrations had to be updated to get rid of `index_together` references
migrations.SeparateDatabaseAndState(
# What actually happens
database_operations=[
migrations.RenameIndex(
model_name="model_name",
new_name="model_xxx_idx",
old_fields=("field1", "field2"),
),
],
# What we want Django to believe happened
state_operations=[
migrations.RemoveIndex(
model_name="model_name",
name="model_xxx_idx_archive",
),
migrations.RenameIndex(
model_name="model_name",
new_name="model_xxx_idx",
old_fields=("field1", "field2"),
),
],
),
]