Удалить дубликаты в запросе Django - PullRequest
31 голосов
/ 04 мая 2011

Есть ли простой способ удалить дубликаты в следующем базовом запросе -

email_list = Emails.objects.order_by('email')

Я пытался использовать duplicate (), но он не работал.Не могли бы вы показать мне точный синтаксис для выполнения этого запроса без дубликатов?Спасибо.

Ответы [ 6 ]

87 голосов
/ 04 мая 2011

Этот запрос не даст вам дубликатов, т. Е. Он даст вам все строки в базе данных, упорядоченные по электронной почте.

Однако я предполагаю, что вы имеете в виду, что у вас есть дубликаты данных в вашей базе данных. Добавление distinct() здесь не поможет, потому что даже если у вас есть только одно поле, у вас также есть автоматическое поле id, поэтому комбинация id + email не уникальна.

Предполагая, что вам нужно только одно поле, email_address, без дубликатов, вы можете сделать это:

email_list = Email.objects.values_list('email', flat=True).distinct()

Однако вы должны действительно решить проблему с корнем и удалить дубликаты данных из вашей базы данных.

Пример, удаление дубликатов писем по электронной почте:

for email in Email.objects.values_list('email', flat=True).distinct():
    Email.objects.filter(pk__in=Email.objects.filter(email=email).values_list('id', flat=True)[1:]).delete()

Или книги по имени:

for name in Book.objects.values_list('name', flat=True).distinct(): 
    Book.objects.filter(pk__in=Artwork.objects.filter(name=name).values_list('id', flat=True)[3:]).delete()
8 голосов
/ 04 мая 2011

Вы можете связать .distinct() в конце вашего набора запросов, чтобы отфильтровать дубликаты. Проверить: http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.distinct

6 голосов
/ 17 марта 2016

Для проверки дубликата вы можете сделать GROUP_BY и HAVING в Django, как показано ниже. Мы используем Django annotations здесь.

from django.db.models import Count
from app.models import Email

duplicate_emails = Email.objects.values('email').annotate(email_count=Count('email')).filter(email_count__gt=1)

Теперь перебираем вышеприведенные данные и удаляем все остальные emails, кроме первой (зависит от требований или чего-либо еще).

for data in duplicates_emails:
    email = data['email']
    Email.objects.filter(email=email).order_by('pk')[1:].delete()
5 голосов
/ 04 мая 2011

Вы можете использовать функцию distinct(), в зависимости от вашей модели.Если вы хотите получить только одно поле из модели, вы можете сделать что-то вроде:

email_list = Emails.objects.values_list('email').order_by('email').distinct()

, которое должно дать вам упорядоченный список электронных писем.

2 голосов
/ 20 июня 2017

Вы также можете использовать set()

email_list = set(Emails.objects.values_list('email', flat=True))
0 голосов
/ 13 февраля 2015

Я использовал следующее, чтобы фактически удалить дубликаты записей из базы данных, надеюсь, это поможет кому-то еще.

adds = Address.objects.all()
d = adds.distinct('latitude', 'longitude')
for address in adds:    
  if i not in d:
    address.delete()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...