将Django模型迁移到unique_together约束 [英] Migrate Django model to unique_together constraint

查看:156
本文介绍了将Django模型迁移到unique_together约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有三个字段的模型

  class MyModel(models.Model):
a = models.ForeignKey (A)
b = models.ForeignKey(B)
c = models.ForeignKey(C)

我想在这些字段之间强制执行一个唯一约束,并找到django的 unique_together ,这似乎是解决方案。但是,我已经有一个现有的数据库,并且有很多重复。我知道,由于 unique_together 在数据库级别工作,所以我需要唯一的行,然后尝试迁移。


$ b $有没有一个很好的方法去删除重复(重复的是相同的(A,B,C)),以便我可以运行迁移来获取 unique_together contstraint?

解决方案

如果您乐意任意选择一个重复项,我认为以下可能会做的。也许不是最有效率但是足够简单,我猜你只需要运行一次。请验证这一切都可以在一些测试数据上工作,以防万一我做了一些愚蠢的事情,因为你要删除一堆数据。



首先我们找到一组形成重复的对象。对于每个组,(任意地)选择我们要保留的主人。我们选择的方法是选择最低的 pk

  master_pks = MyModel.objects.values('A','B','C'
).annotate(Min('pk'),count = Count('pk')
).filter(count__gt = 1
).values_list('pk__min',flat = True)

然后我们循环每个主人,并删除其所有的重复项目

  masters = MyModel.objects.in_bulk(list(master_pks))
$ masters.values()中的b $ b:
MyModel.objects.filter(a = master.a,b = master.b,c = master.c
).exclude(pk = master .pk).del_ACCIDENT_PREVENTION_ete()


I have a model with three fields

class MyModel(models.Model):
    a    = models.ForeignKey(A)
    b    = models.ForeignKey(B)
    c    = models.ForeignKey(C)

I want to enforce a unique constraint between these fields, and found django's unique_together, which seems to be the solution. However, I already have an existing database, and there are many duplicates. I know that since unique_together works at the database level, I need to unique-ify the rows, and then try a migration.

Is there a good way to go about removing duplicates (where a duplicate has the same (A,B,C)) so that I can run migration to get the unique_together contstraint?

解决方案

If you are happy to choose one of the duplicates arbitrarily, I think the following might do the trick. Perhaps not the most efficient but simple enough and I guess you only need to run this once. Please verify this all works yourself on some test data in case I've done something silly, since you are about to delete a bunch of data.

First we find groups of objects which form duplicates. For each group, (arbitrarily) pick a "master" that we are going to keep. Our chosen method is to pick the one with lowest pk

master_pks = MyModel.objects.values('A', 'B', 'C'
    ).annotate(Min('pk'), count=Count('pk')
    ).filter(count__gt=1
    ).values_list('pk__min', flat=True)

we then loop over each master, and delete all its duplicates

masters = MyModel.objects.in_bulk( list(master_pks) )

for master in masters.values():
    MyModel.objects.filter(a=master.a, b=master.b, c=master.c
        ).exclude(pk=master.pk).del_ACCIDENT_PREVENTION_ete()

这篇关于将Django模型迁移到unique_together约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆