Django ОРМ. Выбрать только дублированные поля из БД - PullRequest
2 голосов
/ 20 апреля 2020

У меня есть таблица в БД, например:

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

Мне нужно удалить все объекты, где есть повторяющиеся поля пользователь, значение и текст , но сохранить один из них. В этом примере будет удалена 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.

Кто-нибудь может мне помочь?

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Сначала вы должны знать, как работает count . Метод Count будет подсчитывать для идентичных строк . Он использует все поля , доступные в объекте, чтобы проверить, совпадает ли он с полями других строк или нет. Таким образом, в текущей ситуации count_values ​​ приводит к 1 , потому что Count использует все поля, кроме id , для поиска похожих строк. Подсчет включает в себя поля пользователя, значения, текста, что-то1, что-то2 для проверки на сходство.

Для подсчета строк с похожими полями необходимо использовать только поле пользователя, значения и текстовое поле

Запрос:

  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}]

с использованием этого queryset Вы можете проверить, сколько раз строка содержит пользователя, значения и текстовое поле с одинаковыми значениями

0 голосов
/ 20 апреля 2020

Будет ли Python l oop работать на вас?

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()
...