unique_fields = ['field_1', …, 'field_n']
duplicates = (MyModel.objects.values(*unique_fields)
.order_by()
.annotate(max_id=models.Max('id'),
count_id=models.Count('id'))
.filter(count_id__gt=1))
for duplicate in duplicates:
(MyModel.objects.filter(**{x: duplicate[x] for x in unique_fields})
.exclude(id=duplicate['max_id'])
.delete())
Bạn không nên làm điều đó thường xuyên. Thay vào đó hãy sử dụng các ràng buộc unique_together
trên cơ sở dữ liệu.
tiềm ẩn mã SQL
Khi chú thích django ORM sử dụng GROUP BY
tuyên bố trên tất cả các lĩnh vực mô hình sử dụng trong truy vấn. Vì vậy, việc sử dụng phương thức .values()
. GROUP BY
sẽ nhóm tất cả các bản ghi có các giá trị giống hệt nhau. Những người được sao chép (nhiều hơn một số id
cho unique_fields
) sau đó được lọc ra trong câu hỏi HAVING
được tạo bởi .filter()
trên chú thích QuerySet
.
SELECT
field_1,
…
field_n,
MAX(id) as max_id,
COUNT(id) as count_id
FROM
app_mymodel
GROUP BY
field_1,
…
field_n
HAVING
count_id > 1
Các bản ghi trùng lặp sau đó sẽ bị xóa trong vòng for
ngoại trừ bản ghi thường xuyên nhất cho mỗi nhóm.
.order_by rỗng()
Chỉ cần chắc chắn, nó luôn luôn khôn ngoan để thêm một sản phẩm nào .order_by()
gọi trước khi tập hợp một QuerySet
.
Các trường được sử dụng để đặt hàng QuerySet
cũng được bao gồm trong tuyên bố GROUP BY
. Làm trống .order_by()
ghi đè các cột được khai báo trong mô hình Meta
và kết quả là chúng không được bao gồm trong truy vấn SQL (ví dụ: sắp xếp mặc định theo ngày có thể làm hỏng kết quả).
Bạn có thể không cần phải ghi đè lên tại thời điểm hiện tại, nhưng ai đó có thể thêm thứ tự mặc định sau đó và do đó làm hỏng mã xóa trùng lặp quý giá của bạn thậm chí không biết điều đó. Có, tôi chắc chắn bạn có 100% phạm vi kiểm tra…
Chỉ cần thêm trống .order_by()
để an toàn. ;-)
https://docs.djangoproject.com/en/1.11/topics/db/aggregation/#interaction-with-default-ordering-or-order-by
giao dịch
Tất nhiên bạn nên xem xét làm việc đó tất cả trong một giao dịch duy nhất.
https://docs.djangoproject.com/en/1.11/topics/db/transactions/#django.db.transaction.atomic
Cảm ơn! Tuy nhiên, để tôi có thể hiểu (tôi vẫn còn rất nhiều người mới làm quen với Django), bạn có thể giải thích điều gì đang xảy ra ở mỗi bước không? Tôi hiểu rằng 'MyModel.objects.values (* unique_fields)' tạo ra một bộ từ điển, với mỗi từ điển liên quan đến một đối tượng. Nhưng sau đó tôi bị lạc - chú thích đang làm gì? – Westerley
Tôi hy vọng bản cập nhật của tôi sẽ làm rõ mọi thứ một chút. –
Brilliant! Hoạt động hoàn hảo!Nó đã cho tôi khá nhiều nghiên cứu và suy nghĩ để tìm ra chính xác ** cách nó hoạt động (lời giải thích của bạn đã giúp khá nhiều và giúp tôi tìm ra những gì tôi phải đọc ...) nhưng làm việc được! Cảm ơn một lần nữa (và xin lỗi vì sự chậm trễ trong việc trở lại này) – Westerley