簡體   English   中英

如何使用Django 1.6批量保存對象

[英]How can I save objects in bulk with django 1.6

我正在尋找一種比在每個對象上調用.save()更有效地更新多個對象的方法。

我有代碼,它使用.filter()加載對象。 然后,它與外部服務進行通信,以決定需要對每個對象執行什么操作。 最后,我有一個具有更新值的對象列表,需要保存。

這段代碼有效,但是太慢了:

for o in l: o.save()

搜索到目前為止我發現的建議.bulk_create().update()

bulk_create非常適合新對象。 但是,用model.objects.bulk_create(l)替換上述循環會產生IntegrityError: UNIQUE constraint failed: ,可能是因為它試圖創建新對象而不是更新現有對象。

使用.update()似乎也不適用於我的用例,因為它將用相同的值更新集合中的所有對象。 就我而言,我為每個對象計算了一個不同的值,需要保存。

是否有比在每個對象上調用.save()更快的解決方案?

您可以嘗試在修改對象時在對象中設置has_changed標志,然后僅保存has_changed為True的對象。

這是基於並非所有對象都總是被修改的假設。 如果所有對象始終都在變化,那不是解決方案。

Django無法執行此操作,因為(通常)您的數據庫無法執行此操作。 沒有一個SQL語句可以用不同的值更新不同的行。 (諸如使用CASE...WHEN類的特殊異常不太可能在這里提供幫助。)

如果很多或大多數對象是新對象,則可以跟蹤哪些對象並使用bulk_create創建bulk_create 否則,迭代並執行save()可能是您最好的選擇。

您可能會考慮使用線程並行化過程,尤其是在與外部服務進行通信的延遲較大時。

我發現此解決方法:

class CASE(object):
    def __init__(self, field_name, objects):
        self.field_name = field_name
        self.objects = objects

    def __unicode__(self): return self

    def as_sql(self, qn, connection):
        sql = [ 'CASE id' ]
        params = []
        for o in self.objects:
            sql.append('WHEN %s THEN %s')
            params.append(o.pk)
            params.append(getattr(o, self.field_name))
        sql.append('ELSE')
        sql.append(qn(self.field_name))
        sql.append('END')
        return (' '.join(sql), params)

model.objects.update(value=CASE('value', l))

它並不漂亮,但據我所知,只要我更新一個文本字段,它就可以生成正確且有效的SQL。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM