2016-04-17 9 views
0

Ich verwende bulk_create, um Objekte eines Modells zu erstellen. Wann immer eine Ausnahme ausgelöst wird, wie gehe ich damit um?Wie behandle ich Ausnahmen mit Django objects.bulk_create()

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

Student.objects.bulk_create(aList) 

als Modell hat, das Feld nameunique=True ist, ich habe die Eingänge zu verarbeiten, als die Ausnahme. Wie gehe ich mit Ausnahmen einzeln um?

Diese funktionieren nicht wie beabsichtigt,

try: 
    # bulk_create 
except: 
    # handlers 

als die Ausnahme ausgelöst wird, der bulk_create Prozess beendet wird.

PS. Ich freue mich auf die bulk_create. keine Schleifen mit create oder update_or_create oder get_or_create

Antwort

0

Nun, das ist unmöglich. Das ist, wie bulk_create definiert:

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 

Und die _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) 

So, wie Sie bulk_create ist im Grunde eine for Schleife innerhalb eines transaction.atomic sehen können.

Eine weitere Sache. Es ist auch nicht möglich, nur einige Einträge innerhalb des Transaktionsblocks zu speichern. Es wird entweder vollständig ausgeführt oder überhaupt nicht ausgeführt.

Verwandte Themen