簡體   English   中英

如何處理 Django objects.bulk_create() 的異常

[英]How do I handle exceptions with Django objects.bulk_create()

我正在使用bulk_create創建一個 model 的對象。每當出現異常時,我該如何處理?

aList = [
    Student(name="Jason"),
    Student(name="Mark"),
    Student(name="Tom"),
    Student(name="Jason"),
    Student(name="Tom"),
]

Student.objects.bulk_create(aList)

由於 model 的字段nameunique=True ,我必須在引發異常時處理輸入。 我如何一一處理異常。

這不按預期工作,

try:
    # bulk_create
except:
    # handlers

引發異常時, bulk_create進程終止。

附言。 我很期待bulk_create 沒有使用createupdate_or_createget_or_create的循環

嗯,那是不可能的。 這就是bulk_create的定義方式:

def bulk_create(self, objs, batch_size=None):
        for parent in self.model._meta.get_parent_list():
            if parent._meta.concrete_model is not self.model._meta.concrete_model:
                raise ValueError("Can't bulk create a multi-table inherited model")
        if not objs:
            return objs
        self._for_write = True
        connection = connections[self.db]
        fields = self.model._meta.concrete_fields
        objs = list(objs)
        self._populate_pk_values(objs)
        with transaction.atomic(using=self.db, savepoint=False):
            if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk
                    and self.model._meta.has_auto_field):
                self._batched_insert(objs, fields, batch_size)
            else:
                objs_with_pk, objs_without_pk = partition(lambda o: o.pk is None, objs)
                if objs_with_pk:
                    self._batched_insert(objs_with_pk, fields, batch_size)
                if objs_without_pk:
                    fields = [f for f in fields if not isinstance(f, AutoField)]
                    self._batched_insert(objs_without_pk, fields, batch_size)

        return objs

_batched_insert

def _batched_insert(self, objs, fields, batch_size):
    """
    A little helper method for bulk_insert to insert the bulk one batch
    at a time. Inserts recursively a batch from the front of the bulk and
    then _batched_insert() the remaining objects again.
    """
    if not objs:
        return
    ops = connections[self.db].ops
    batch_size = (batch_size or max(ops.bulk_batch_size(fields, objs), 1))
    for batch in [objs[i:i + batch_size]
                  for i in range(0, len(objs), batch_size)]:
        self.model._base_manager._insert(batch, fields=fields,
                                         using=self.db)

所以,你可以看到bulk_create基本上是一個for內部循環transaction.atomic

還有一件事。 也不可能只保存交易塊內的一些條目。 它要么完全執行,要么根本不執行。

實際上有一個標志ignore_conflicts=False ,它捕獲異常,所以嘗試ModelName.objects.bulk_create([ModelName(name='spam', slug='eggs')...], ignore_conflicts=True)

你可以通過做來處理它

 objs = [(Event), (Event), (Event)...] try: Event.objects.bulk_create(objs) except IntegrityError: for obj in objs: try: obj.save() except IntegrityError: continue

暫無
暫無

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

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