Django迁移执行失败修复:为解决唯一字段重复键添加去重代码
解决Django添加unique字段时因重复键导致迁移失败的问题
嘿,你这个思路完全没问题——遇到重复键导致迁移失败,先清理库里的重复数据再加约束,这就是正确的解决方向!不过你现在写的代码有几个可以优化的地方,不管是性能还是数据安全性上都能更稳妥,我给你捋捋:
首先,你原来的代码里有个小错误:apps.get_model的第一个参数应该是你的app标签(就是INSTALLED_APPS里注册的projects),而不是完整的模型路径'myapp.projects.models',这个错误可能会导致迁移时找不到模型哦。
然后,遍历每一行再执行count查询的方式,数据量大的时候会特别慢,而且逻辑上会把所有重复行都删掉(除了最后剩下的那一个),没法控制保留哪一条。咱们换个更高效的方式:先找出所有重复的dir_url,然后每组里保留你需要的那条(比如最新创建的),删掉其他的。
优化后的迁移代码是这样的:
from django.db import migrations, models def remove_duplicates(apps, schema_editor): # 注意这里的模型获取方式:app标签是'projects',模型名是'Dir' Dir = apps.get_model('projects', 'Dir') # 第一步:找出所有有重复的dir_url duplicate_urls = Dir.objects.values('dir_url') \ .annotate(duplicate_count=models.Count('id')) \ .filter(duplicate_count__gt=1) # 第二步:遍历每个重复的url,保留最新的那条,删掉其他 for url_entry in duplicate_urls: dir_url = url_entry['dir_url'] # 按id倒序排列,取从第2条开始的所有记录(也就是除了最新的那条之外的重复项) duplicate_records = Dir.objects.filter(dir_url=dir_url).order_by('-id')[1:] duplicate_records.delete() class Migration(migrations.Migration): dependencies = [ ('projects', '0021_auto_20180412_1215'), ] operations = [ # 先执行清理重复数据的操作 migrations.RunPython(remove_duplicates), # 再添加unique约束(这里的字段类型根据你实际情况调整,比如CharField、URLField等) migrations.AlterField( model_name='dir', name='dir_url', field=models.URLField(unique=True), ), ]
还有几个关键的注意事项要提醒你:
- 先备份再操作:生产环境执行迁移前,一定要先备份数据库!万一清理逻辑不符合预期,还能回滚数据。
- 测试环境先验证:先在测试环境跑一遍这个迁移,确认重复数据清理的结果是你想要的(比如确实保留了最新的记录),再部署到生产。
- 按需调整保留逻辑:如果业务上需要保留最早创建的记录,把
order_by('-id')改成order_by('id')就行;如果有其他业务字段(比如created_at),用那个字段排序会更准确。
这样调整之后,迁移应该就能顺利完成了,而且处理大数据量的时候也不会拖慢服务器~
内容的提问来源于stack exchange,提问作者Arti
相关产品推荐
相关产品推荐

