如何引入独特的和冲突的数据?
How to introduce unique together with conflicting data?
我为我的网站编写了一些 qna 脚本,为了防止用户发起讨论,我希望每个用户只能回复一次。
class Q(models.Model):
text = models.TextField()
user = models.ForeignKeyField('auth.User')
class A(models.Model):
text = models.TextField()
user = models.ForeignKeyField('auth.User')
q = models.ForeignKeyField('Q')
class Meta:
unique_together = (('user','q'),)
现在迁移给我:
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: columns user_id, q_id are not unique
当然,唯一性与现有数据冲突。我现在需要知道的是如何告诉迁移删除冲突的答案。保留第一个被发现的愚蠢解决方案已经是一个很大的帮助。更好的方法是通过自定义函数比较冲突的 A 。
我正在使用新的迁移系统运行 Django-1.7 - 而不是 South。
感谢您的帮助!
您只需要创建一个数据迁移,您确实可以在其中编写自定义函数来使用您想要的任何逻辑。有关详细信息,请参阅 the documentation。
例如,仅保留最低 Answer
id
(这应该是最早答案的良好代表)的数据迁移可能如下所示:
from django.db import models, migrations
def make_unique(apps, schema_editor):
A = apps.get_model("yourappname", "A")
# get all unique pairs of (user, question)
all_user_qs = A.objects.values_list("user_id", "q_id").distinct()
# for each pair, delete all but the first
for user_id, q_id in all_user_qs:
late_answers = A.objects.filter(user_id=user_id, q_id=q_id).order_by('id')[1:]
A.objects.filter(id__in=list(late_answers)).delete()
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(make_unique),
]
(这超出了我的头脑,当然是破坏性的,所以请仅以此为例。在执行所有这些删除操作之前,您可能需要考虑备份数据。)
回顾一下:删除您尝试 运行 的迁移并摆脱唯一约束。如文档中所述创建空数据迁移。编写一个函数来删除当前存在于数据库中的非唯一数据。然后将唯一约束添加回 运行 makemigrations
。最后,运行 两个迁移都带有 migrate
。
我为我的网站编写了一些 qna 脚本,为了防止用户发起讨论,我希望每个用户只能回复一次。
class Q(models.Model):
text = models.TextField()
user = models.ForeignKeyField('auth.User')
class A(models.Model):
text = models.TextField()
user = models.ForeignKeyField('auth.User')
q = models.ForeignKeyField('Q')
class Meta:
unique_together = (('user','q'),)
现在迁移给我:
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: columns user_id, q_id are not unique
当然,唯一性与现有数据冲突。我现在需要知道的是如何告诉迁移删除冲突的答案。保留第一个被发现的愚蠢解决方案已经是一个很大的帮助。更好的方法是通过自定义函数比较冲突的 A 。
我正在使用新的迁移系统运行 Django-1.7 - 而不是 South。
感谢您的帮助!
您只需要创建一个数据迁移,您确实可以在其中编写自定义函数来使用您想要的任何逻辑。有关详细信息,请参阅 the documentation。
例如,仅保留最低 Answer
id
(这应该是最早答案的良好代表)的数据迁移可能如下所示:
from django.db import models, migrations
def make_unique(apps, schema_editor):
A = apps.get_model("yourappname", "A")
# get all unique pairs of (user, question)
all_user_qs = A.objects.values_list("user_id", "q_id").distinct()
# for each pair, delete all but the first
for user_id, q_id in all_user_qs:
late_answers = A.objects.filter(user_id=user_id, q_id=q_id).order_by('id')[1:]
A.objects.filter(id__in=list(late_answers)).delete()
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(make_unique),
]
(这超出了我的头脑,当然是破坏性的,所以请仅以此为例。在执行所有这些删除操作之前,您可能需要考虑备份数据。)
回顾一下:删除您尝试 运行 的迁移并摆脱唯一约束。如文档中所述创建空数据迁移。编写一个函数来删除当前存在于数据库中的非唯一数据。然后将唯一约束添加回 运行 makemigrations
。最后,运行 两个迁移都带有 migrate
。