我有一個模型,由於代碼錯誤,有重複的行。我現在需要刪除數據庫中的任何重複項。刪除Django數據庫中的重複行
每行都應該有一個唯一的photo_id。有沒有簡單的方法來刪除它們?或者我需要做這樣的事情:
rows = MyModel.objects.all()
for row in rows:
try:
MyModel.objects.get(photo_id=row.photo_id)
except:
row.delete()
我有一個模型,由於代碼錯誤,有重複的行。我現在需要刪除數據庫中的任何重複項。刪除Django數據庫中的重複行
每行都應該有一個唯一的photo_id。有沒有簡單的方法來刪除它們?或者我需要做這樣的事情:
rows = MyModel.objects.all()
for row in rows:
try:
MyModel.objects.get(photo_id=row.photo_id)
except:
row.delete()
最簡單的方法是最簡單的方法!特別是對於那些性能甚至不重要的腳本(除非它確實如此)。既然不是核心代碼,我只想寫出第一個想到的事情,作品。
# assuming which duplicate is removed doesn't matter...
for row in MyModel.objects.all():
if MyModel.objects.filter(photo_id=row.photo_id).count() > 1:
row.delete()
一如既往,備份之前,你做這個東西。
謝謝。你知道一個查詢會告訴我什麼是行嗎?我知道截然不同的人會告訴我沒有軍人的數據庫,但是什麼會讓我看到軍人? – Brenden
'SELECT * FROM table GROUP BY photo_id HAVING COUNT(photo_id)> 1;' –
@brenden,而不是刪除行,您可以將它們追加到列表中?我刪除了我的第二個查詢,因爲我忘記了會匹配重複項和非重複項......關閉一個! –
這可能會更快,因爲它避免了MyModel中每行的內部過濾器。由於ID是唯一的,如果模型按遞增順序排序,我們可以跟蹤我們看到的最後一個ID,並且當我們在行上行走時,如果我們看到具有相同ID的模型,它必須是重複的,所以我們可以刪除它。
lastSeenId = float('-Inf')
rows = MyModel.objects.all().order_by('photo_id')
for row in rows:
if row.photo_id == lastSeenId:
row.delete() # We've seen this id in a previous row
else: # New id found, save it and check future rows for duplicates.
lastSeenId = row.photo_id
這裏是一個快速的解決方案:
from django.db import connection
query = "SELECT id FROM table_name GROUP BY unique_column HAVING COUNT(unique_column)>1"
cursor = connection.cursor()
cursor.execute(query)
ids_list = [item[0] for item in cursor.fetchall()]
現在你可以這樣做:
Some_Model.objects.filter(id__in=ids_list).delete()
,或者如果ids_list
是太龐大你的DBMS處理
你可以將其分割爲可以由其處理的塊:
seg_length = 100
ids_lists = [ids_list[x:x+seg_length] for x in range(0,len(ids_list),seg_length)]
for ids_list in ids_lists:
SomeModel.objects.filter(id__in=ids_list).delete()
這將只刪除其中的一個副本。所以如果有超過2行的話,你必須遞歸地做這件事。所以它可能不會比其他解決方案更快。 – hobs
將來會更好,將該字段定義爲數據庫模式中唯一的字段。然後你消除這個問題從來沒有發生過。實際上,您應該將這些細節添加到所有數據庫模式中。 – Keith