码迷,mamicode.com
首页 > 其他好文 > 详细

[Django]bulk_create 探究

时间:2014-12-08 19:41:18      阅读:615      评论:0      收藏:0      [点我收藏+]

标签:django   批量   插入   bulk_create   源码   

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

查看了源码(django1.5):在 django/db/models/query.py 中,看到这样的片段
with transaction.commit_on_success_unless_managed(using=self.db):
            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)

这里我们看到了一个transaction的调用 transaction.commit_on_success_unless_managed(using=self.db),那么这句话是什么意思呢?
看看他的定义: django/db/transaction.py中
def commit_on_success_unless_managed(using=None, savepoint=False):
    """
    Transitory API to preserve backwards-compatibility while refactoring.
 
    Once the legacy transaction management is fully deprecated, this should
    simply be replaced by atomic. Until then, it's necessary to guarantee that
    a commit occurs on exit, which atomic doesn't do when it's nested.
 
    Unlike atomic, savepoint defaults to False because that's closer to the
    legacy behavior.
    """
    connection = get_connection(using)
    if connection.get_autocommit() or connection.in_atomic_block:
        return atomic(using, savepoint)
    else:
        def entering(using):
            pass
 
        def exiting(exc_type, using):
            set_dirty(using=using)
 
        return _transaction_func(entering, exiting, using)

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

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

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


[Django]bulk_create 探究

标签:django   批量   插入   bulk_create   源码   

原文地址:http://blog.csdn.net/orangleliu/article/details/41806263

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!