2017-08-15 10 views
0

我有點奇怪的問題,我不能解釋。Django使用分頁刪除查詢集,沒有捕獲到集合的所有部分

我有一個django項目,周圍有一些陳舊的舊物體。例如,可以說我的對象看起來像這樣:

class blog_post(models.Model): 
    user_account = models.ForeignKey('accounts.Account') 
    text = models.CharField(max_length=255) 
    authors = models.ManyToManyField(author) 
    created = models.DateTimeField(blank=True, null=True) 

這不是我的模型的確切副本,但足夠接近。

我創建了一個管理命令來構建這些有序的對象的查詢集,然後用分頁程序刪除與

我的命令看起來是這樣的:

all_accounts = Account.objects.all() 
for act in all_accounts.iterator(): 
    stale_objects = blog_post.objects.filter(user_account=act, 
    created=django.utils.timezone.now() - datetime.timedelta(days=7)) 

    paginator = Paginator(stale_objects.order_by('id'), 100) 
    for page in range(1, paginator.num_pages + 1): 
     page_stale_objects = blog_post.objects.filter(id__in=paginator.page(page).object_list.values_list('id')) 
     page_stale_objects.delete() 

的問題我有在我用命令刪除這些對象之後,仍然存在適合查詢集參數但不會被刪除的對象。所以,我必須運行該命令3次以正確查找並刪除所有對象。

我首先想到我的日期範圍只是奇怪的在DateTime的邊緣,所以沒有捕獲在我的命令時間後不到1周的對象。事實並非如此,我已經從查詢集中刪除了created = ...過濾器,並得到了相同的結果。

爲什麼我的查詢集在第一次運行此命令時沒有捕獲所有對象?沒有過多的物體,最多約30,000行。

+0

Paginator分頁您的數據。我假設如果你刪除'page_stale_objects',那麼只會刪除1個頁面(這意味着你發現的對象數量超過了paginator的'per_page'值) –

回答

0

通過查詢集分頁被翻譯成連續的LIMIT/OFFSET調用。所以,想想序列:

  • 得到與項目偏移量爲0,並從偏移21

限制20

  • 刪除這些項目
  • 得到下一個頁面,即20項別急!一旦我們刪除了第一組,查詢集現在又從0開始。現在從0到20的項目被跳過。

    解決的辦法是,不要這樣做。分頁用於顯示對象,而不是刪除它們。

  • +0

    嗯,是的,這是我開始通過一些更多的測試開始形成的。謝謝。 – rob

    0

    我不明白你爲什麼要使用Paginator如果你只是想刪除你的查詢集。糾正我,如果我錯了,但看起來像你正在做以下幾點:

    • 得到查詢集
    • 排序這個查詢集的ID
    • 拼版它
    • 從每個列表獲取對象
    • 刪除他們

    當你可能只是這樣做:

    • 得到查詢集
    • 刪除查詢集

    這將是一個巨大的性能提升,如果你有大量的對象。

    所以,我建議你只是這樣做:

    stale_objects = blog_post.objects.filter(...) 
    stale_objects.delete() 
    

    希望它能幫助!

    +0

    這並不是真的試圖回答核心問題,另外我已經顯示了對查詢集刪除的理解。但是,爲了回答你的問題,我這樣做的原因有以下幾個:1)在此過程中有更新或刪除的其他相關對象,以及2)在大型查詢集上使用delete()需要更長的時間刪除而不是通過分頁和刪除一個子集。我已經測試了很多次,發現它適用於我所有的情況。 – rob