我正在使用Django 2.1,Python 3.6和MySQL 8。
数据库的表很大,有很多大行,因此迁移到该表需要花费数小时才能完成。我发现如果我从该表中删除全文索引,它将启用inplace alghorithm修改表-它的速度更快。
所以我需要在Django中利用它。我考虑过将全文索引删除为第一个迁移操作,并在所有其他操作之后再次创建它。
operations = [
migrations.CreateModel(
name='NewModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'abstract': False,
},
),
migrations.RunSQL(
('DROP INDEX fulltext_idx_content ON summarizer_model',),
('CREATE FULLTEXT INDEX fulltext_idx_content ON summarizer_model(content)',),
),
migrations.AddField(
model_name='model',
name='new_model',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='new_models_objects', to='summarizer.new_model'),
),
migrations.RunSQL(
('CREATE FULLTEXT INDEX fulltext_idx_content ON summarizer_model(content)',),
('DROP INDEX fulltext_idx_content ON summarizer_model',),
),
]
((我在代码窃听器上方迅速将其“匿名化”,因此,如果存在一些逻辑错误,请原谅-这里不是这种情况:))]
问题是,Django迁移总是将添加ForeignKey约束作为最后一个操作。因此,在我的最后一个RunSQL
之后创建了索引。这使其操作非常慢(用新列复制整个表)。
是否有克服的方法?我猜想仅将另一个迁移文件用于索引创建会很奇怪。我只想在迁移时临时删除索引。
谢谢
[在深入研究Django迁移的内部之后,我发现Django中的某些迁移操作将SQL添加到架构对象中的deferred_sql
列表中。因此,知道解决我的问题的方法是从RunSQL
操作继承。我没有立即执行SQL,而是将其附加到deferred_sql
列表中,...就是这样!
class DeferredForwardRunSQL(RunSQL):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
schema_editor.deferred_sql.append(self.sql[0])
我还需要从迁移中修改最后一个RunSQL操作:
operations = [
migrations.CreateModel(
name='NewModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'abstract': False,
},
),
migrations.RunSQL(
('DROP INDEX fulltext_idx_content ON summarizer_model',),
('CREATE FULLTEXT INDEX fulltext_idx_content ON summarizer_model(content)',),
),
migrations.AddField(
model_name='model',
name='new_model',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='new_models_objects', to='summarizer.new_model'),
),
DeferredForwardRunSQL(
('CREATE FULLTEXT INDEX fulltext_idx_content ON summarizer_model(content)',),
('DROP INDEX fulltext_idx_content ON summarizer_model',),
),
]
倒退效果也很好