我在数据库中有这样的表:
MyTableWithValues
id | user(fk to Users) | value(fk to Values) | text | something1 | something2 ...
1 | userobject1 | valueobject1 |asdasdasdasd| 123 | 12321
2 | userobject2 | valueobject50 |QWQWQWQWQWQW| 515 | 5555455
3 | userobject1 | valueobject1 |asdasdasdasd| 12345 | 123213
我需要删除重复字段user,value和text的所有对象,但是要从中保存一个。在此示例中,将删除第3条记录。
如何使用Django ORM做到这一点?
PS:试试这个:
recs = (
MyTableWithValues.objects
.order_by()
.annotate(max_id=Max('id'), count_id=Count('user__id'))
#.filter(count_id__gt=1)
.annotate(count_values=Count('values'))
#.filter(count_icd__gt=1)
)
...
...
for r in recs:
print(r.id, r.count_id, , r.count_values)
它打印出这样的内容:
1 1 1
2 1 1
3 1 1
...
尽管事实是,数据库中存在重复的值。我不明白,为什么Count函数不起作用。
有人可以帮我吗?
Python循环会为您工作吗?
import collections
d = collections.defaultdict(list)
# group all objects by the key
for e in MyTableWithValues.objects.all():
k = (e.user_id, e.value_id, e.text)
d[k].append(e)
for k, obj_list in d.items():
if len(obj_list) > 1:
for e in obj_list[1:]:
# except the first one, delete all objects
e.delete()
您应该首先了解count的工作方式。Count方法将对相同的行进行计数。它使用对象中所有可用的fields来检查它是否与other rows的字段相同。因此,在当前情况下,count_values的结果为[[1,因为Count使用除id之外的所有字段来查找相似的行。计数包括用于检查相似性的用户,值,文本,something1,something2字段。
要计算具有相似字段的行,您只需要使用用户,值和文本字段
查询: recs = MyTableWithValues.objects
.values('user','values','text')
.annotate(max_id=Max('id'),count_id=Count('user__id'))
.annotate(count_values=Count('values'))
它将返回字典列表
print(recs)
输出:
<QuerySet[{'user':1,'values':1,'text':'asdasdasdasd','max_id':3,'count_id':2,'count_values':2},{'user':2,'values':2,'text':'QWQWQWQWQWQW','max_id':2,'count_id':1,'count_values':1}]
使用此,您可以检查行包含用户,值和具有相同值的文本字段的次数查询集