[Django]bulk_create 探究

使用django orm大批量插入的时候我们可以不使用for循环对一个一个的save而是使用
bulk_create来批量插入,可是使用了这个方法还需要在自己添加一个事务吗? 还是django本身对这个方法进行了事务的封装?

查看了源码(django1.5):在 django/db/models/query.py 中,看到这样的片段
[python]  view plain copy print ?
  1. with transaction.commit_on_success_unless_managed(using=self.db):  
  2.             if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk  
  3.                 and self.model._meta.has_auto_field):  
  4.                 self._batched_insert(objs, fields, batch_size)  
  5.             else:  
  6.                 objs_with_pk, objs_without_pk = partition(lambda o: o.pk is None, objs)  
  7.                 if objs_with_pk:  
  8.                     self._batched_insert(objs_with_pk, fields, batch_size)  
  9.                 if objs_without_pk:  
  10.                     fields= [f for f in fields if not isinstance(f, AutoField)]  
  11.                     self._batched_insert(objs_without_pk, fields, batch_size)  

这里我们看到了一个transaction的调用 transaction.commit_on_success_unless_managed(using=self.db),那么这句话是什么意思呢?
看看他的定义: django/db/transaction.py中
[python]  view plain copy print ?
  1. def commit_on_success_unless_managed(using=None, savepoint=False):  
  2.     """ 
  3.     Transitory API to preserve backwards-compatibility while refactoring. 
  4.   
  5.     Once the legacy transaction management is fully deprecated, this should 
  6.     simply be replaced by atomic. Until then, it's necessary to guarantee that 
  7.     a commit occurs on exit, which atomic doesn't do when it's nested. 
  8.   
  9.     Unlike atomic, savepoint defaults to False because that's closer to the 
  10.     legacy behavior. 
  11.     """  
  12.     connection = get_connection(using)  
  13.     if connection.get_autocommit() or connection.in_atomic_block:  
  14.         return atomic(using, savepoint)  
  15.     else:  
  16.         def entering(using):  
  17.             pass  
  18.    
  19.         def exiting(exc_type, using):  
  20.             set_dirty(using=using)  
  21.    
  22.         return _transaction_func(entering, exiting, using)  

没怎么看懂这个方法的解释,从代码结构来看应该是有事务的。
那自己做个试验把,往数据库批量插入2条数据,一个正确的,一个错误的看看结果如何?

ipython做了个试验
[python]  view plain copy print ?
  1. from mngm.models import Area  
  2. a1=Area(areaname="China", code="CN", parentid='1', level='3')  
  3. a2=Area(id=1, areaname="China", code="CN", parentid='1', level='3')  #错误的记录  
  4. Area.objects.bulk_create([a1, a2])  
  5. IntegrityError: (1062"Duplicate entry '1' for key 'PRIMARY'")  
  6.    
  7. a2=Area(areaname="Chinaa", code="CN", parentid='1', level='3')        #正确的记录  
  8. Area.objects.bulk_create([a1, a2])  
  9. []  
所以这个操作框架已经实现了事务处理,不需要自己再添加事务就好了。

你可能正好不需要这种事务处理,看看
https://rodmtech.net/docs/django/django-bulk_create-without-integrityerror-rollback/

本文出自 “orangleliu笔记本” 博客,转载请务必保留此出处http://blog.csdn.net/orangleliu/article/details/41806263

作者orangleliu 采用署名-非商业性使用-相同方式共享协议

你可能感兴趣的:(django)