[Django]bulk_create 探究

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

查看了源码(django1.5):在 django/db/models/query.py 中,看到这样的片段
[python]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 ? 在CODE上查看代码片 派生到我的代码片
  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 ? 在CODE上查看代码片 派生到我的代码片
  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. [<Area: Area object>, <Area: Area object>]  
所以这个操作框架已经实现了事务处理,不需要自己再添加事务就好了。

你可能正好不需要这种事务处理,看看

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值