You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:04:45