2012-09-03 64 views
1

我有一個Django項目。有MyModelmodels.py。該模型有4 000 000個實例。Django的objects.all()殺死python

我perfom這個腳本:

for m in MyModel.objects.all(): 
    if len(m.phone) < 10 or len(set(m.phone)) <= 2: 
     m.delete() 

但是,它殺死蟒蛇(只是打印 '殺')。

我知道,問題在於實例數量。 但我如何迭代所有這些?

+0

請問哪些任務需要循環訪問所有對象?用數據庫級的批處理操作或巧妙的查詢可能會更好。正如我寫的,另一臺計算機正在咀嚼4百萬個文件;相信我,這是一個足夠大的數據量,你不想觸及所有的數據,尤其是*不是定期的。 – delnan

+0

'MyModel'中有'phone''CharField'。我想用'len(set(phone))<= 2或len(phone)<10'刪除所有實例。我不知道如何查詢它 – imkost

回答

6

您可以嘗試先計數對象,然後用切片版本進行迭代。喜歡的東西:

step = 10 
count = MyModel.objects.count()/step 
for i in xrange(count): 
    for m in MyModel.objects.all()[i*step:(i+1)*step]: 
     # doing something with m 
+0

謝謝。有用。它看起來像一個骯髒的黑客,但它的工作原理) – imkost

+1

Nitpick:如果count%step!= 0,你會錯過一些條目。 – XORcist

4

如果使用iterator()代替all(),Django將不緩存查詢集,這應該減少內存使用和提高性能。

for m in MyModel.objects.iterator(): 
    # doing something with m 
+0

好的建議,我不知道django的objects.iterator()。但它也會殺死python。 – imkost

+1

它似乎與DEBUG設置爲False。 – pt2ph8

0

阿列克謝的答案是相當不錯,但他假設的MyModel.objects.count()/step其餘部分是零
所以,他可能忽略了一些領域......

step = 10 
total = MyModel.objects.count() 
count = total//step 
if (total % step != 0):  
    count += 1 


for i in xrange(count): 
    first = i*step 
    last = first + step - 1 
    if last >= total: 
     last = total 

    for m in MyModel.objects.all()[first:last]: 
     # doing something with m